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
@@ -74,7 +74,7 @@ export const GIT_TOOL_DEF = {
74
74
  compressible: true,
75
75
  },
76
76
  description:
77
- 'Run Git here, never through shell. An array (max 10) runs in order and stops on failure; batch read-only commands in one. diff for known changes, status to discover them; history only when needed. git diff or git diff -- <paths> includes untracked files. Set include_stage_ids:true to select changes, then action:stage with diff_id/change_ids. Staging rejects stale or cross-Project diffs and returns selected locations.',
77
+ 'Run Git here, never through shell. An array (max 10) runs in order and stops on failure; batch read-only commands in one. diff for known changes, status to discover them; history only when needed. git diff or git diff -- <paths> includes untracked files. Set include_stage_ids:true to select changes, then action:stage with diff_id/change_ids. Staging rejects stale or cross-Project diffs and returns per-file staged counts.',
78
78
  inputSchema: {
79
79
  type: 'object',
80
80
  properties: {
@@ -142,47 +142,149 @@ function outputLines(value) {
142
142
  return String(value || '').match(/[^\n]*\n|[^\n]+$/g) || [];
143
143
  }
144
144
 
145
- function capOutput(text, limit) {
145
+ // A line cap alone lets a few very long lines (minified files, lockfiles)
146
+ // through, so each command also gets a character budget, and a command array
147
+ // shares one. A cut always states what was omitted and how to page.
148
+ const COMMAND_CHAR_BUDGET = 12_000;
149
+ const ARRAY_CHAR_BUDGET = 24_000;
150
+ const MIN_COMMAND_CHARS = 1_000;
151
+ const LARGE_DIFF_LINES = 200;
152
+ const LARGE_DIFF_HINT =
153
+ 'hint: large diff - run with --stat first for per-file sizes, add -U1 for less context, and page by file with -- <path>';
154
+
155
+ // Line-ending warnings are noise the model cannot act on; the content is unchanged.
156
+ const CRLF_WARNING_RE = /^warning: in the working copy of .* (?:CRLF|LF) will be replaced[^\n]*(?:\n|$)/gm;
157
+ // `index abc..def` carries abbreviated object ids the model never uses; mode
158
+ // changes keep their own `old mode`/`new mode`/`new file mode` lines.
159
+ const DIFF_INDEX_LINE_RE = /^index [0-9a-f,]+\.\.[0-9a-f]+(?: [0-7]+)?\r?(?:\n|$)/gm;
160
+ const PATCH_OPERATIONS = new Set(['diff', 'diff-files', 'diff-index', 'diff-tree', 'show', 'log']);
161
+
162
+ function visibleStderr(value) {
163
+ return String(value || '').replace(CRLF_WARNING_RE, '');
164
+ }
165
+
166
+ function presentStdout(plan, value) {
167
+ const stdout = String(value || '');
168
+ if (plan.operation === 'merge-tree') return stdout.replace(/^Auto-merging .*(?:\r?\n|$)/gm, '');
169
+ if (PATCH_OPERATIONS.has(plan.operation) && /^diff --git /m.test(stdout)) {
170
+ return stdout.replace(DIFF_INDEX_LINE_RE, '');
171
+ }
172
+ return stdout;
173
+ }
174
+
175
+ function normalizeCap(limit) {
176
+ return typeof limit === 'object' ? limit : { lines: limit, chars: COMMAND_CHAR_BUDGET };
177
+ }
178
+
179
+ function capOutput(text, cap) {
146
180
  const lines = outputLines(text);
147
- if (lines.length <= limit) return text;
148
- return appendText(
149
- lines.slice(0, limit).join(''),
150
- `... [${lines.length - limit} more lines omitted; raise output_limit or narrow the command]`
151
- );
181
+ const lineCut = lines.length > cap.lines;
182
+ const kept = lineCut ? lines.slice(0, cap.lines).join('') : text;
183
+ if (kept.length <= cap.chars) {
184
+ return {
185
+ text: lineCut
186
+ ? appendText(
187
+ kept,
188
+ `... [${lines.length - cap.lines} more lines omitted; raise output_limit or narrow the command]`
189
+ )
190
+ : text,
191
+ truncated: lineCut,
192
+ totalLines: lines.length,
193
+ };
194
+ }
195
+ const newline = kept.lastIndexOf('\n', cap.chars - 1);
196
+ const cut = newline > 0 ? newline + 1 : cap.chars;
197
+ const shown = outputLines(kept.slice(0, cut)).length;
198
+ return {
199
+ text: appendText(
200
+ kept.slice(0, cut),
201
+ `... [${lines.length - shown} more lines (${text.length - cut} chars) omitted; output limited to ${cap.chars} chars - narrow the command (-- <path>, -n/--skip) to page]`
202
+ ),
203
+ truncated: true,
204
+ totalLines: lines.length,
205
+ };
152
206
  }
153
207
 
154
208
  function commandResult(plan, result, limit) {
155
- const output = capOutput(appendText(String(result.stdout || ''), String(result.stderr || '')), limit);
209
+ const stdout = presentStdout(plan, result.stdout);
210
+ const capped = capOutput(appendText(stdout, visibleStderr(result.stderr)), normalizeCap(limit));
211
+ let output = capped.text;
212
+ if ((capped.truncated || capped.totalLines > LARGE_DIFF_LINES) && /^diff --git /m.test(stdout)) {
213
+ output = appendText(output, LARGE_DIFF_HINT);
214
+ }
156
215
  if (succeeded(result)) return { text: output, failed: false };
157
216
  const processError = result.error || result.timedOut || result.aborted || result.overflow || result.exitCode == null;
158
- // An exit signal is still a non-zero exit, so a command array stops on it;
159
- // the outcome line only keeps the card from reporting a failure.
160
- const exitHeader = exitSignal(plan, result)
161
- ? `exit ${result.exitCode}\n[outcome: no-match]`
162
- : `exit ${result.exitCode}`;
217
+ if (processError) return { text: appendText(fail(gitFailureReason(plan, result)), output), failed: true };
218
+ const outcome = exitSignal(plan, result);
219
+ if (outcome === 'conflicts') {
220
+ // A conflicted merge-tree is its answer, not a failed command: the array continues.
221
+ return {
222
+ text: appendText(
223
+ `exit ${result.exitCode}\n[outcome: conflicts]\nmerge has conflicts (see the CONFLICT lines); this is a result, not a command failure`,
224
+ output
225
+ ),
226
+ failed: false,
227
+ };
228
+ }
229
+ // A no-match signal is still a non-zero exit, so a command array stops on
230
+ // it; the outcome line only keeps the card from reporting a failure.
163
231
  return {
164
- text: appendText(processError ? fail(gitFailureReason(plan, result)) : exitHeader, output),
232
+ text: appendText(outcome ? `exit ${result.exitCode}\n[outcome: ${outcome}]` : `exit ${result.exitCode}`, output),
165
233
  failed: true,
166
234
  };
167
235
  }
168
236
 
237
+ // Paths come from git unquoted; only a name that would break the one-line
238
+ // listing (control characters, quotes) is JSON-quoted.
239
+ function listedPath(path) {
240
+ return [...path].some((char) => char.charCodeAt(0) < 0x20 || char === '"') ? JSON.stringify(path) : path;
241
+ }
242
+
169
243
  function stageableDiffResult(plan, result, snapshot, limit) {
170
244
  if (!snapshot.diffId) return commandResult(plan, result, limit);
171
245
  const rendered = commandResult(plan, result, limit);
172
- rendered.text = appendText(rendered.text, `diff_id: ${snapshot.diffId}`);
173
- let previousPath;
246
+ // The hunk headers are already in the body; one line per file names the id range.
247
+ const files = [];
174
248
  for (const change of snapshot.changes) {
175
- if (change.path !== previousPath) {
176
- rendered.text = appendText(rendered.text, `file: ${JSON.stringify(change.path)}`);
177
- previousPath = change.path;
178
- }
179
- const location =
180
- change.kind || `@@ -${change.old_start},${change.deletions} +${change.new_start},${change.additions} @@`;
181
- rendered.text = appendText(rendered.text, `change:${change.id} ${location}`);
249
+ const last = files.at(-1);
250
+ if (last?.path === change.path && !change.kind && !last.kind) last.end = change.id;
251
+ else files.push({ path: change.path, start: change.id, end: change.id, kind: change.kind });
182
252
  }
253
+ const listing = files.map(
254
+ ({ path, start, end, kind }) =>
255
+ `${listedPath(path)}: ${start === end ? start : `${start}-${end}`}${kind ? ' [whole file]' : ''}`
256
+ );
257
+ rendered.text = appendText(
258
+ rendered.text,
259
+ [
260
+ `diff_id: ${snapshot.diffId} (ids number the +/- runs in diff order; [whole file] ids stage the entire file)`,
261
+ ...listing,
262
+ ].join('\n')
263
+ );
183
264
  return rendered;
184
265
  }
185
266
 
267
+ // Per-file staged counts; the paths and ranges the model already holds are not repeated per change.
268
+ function stagedSummary(changes) {
269
+ const files = new Map();
270
+ for (const { path, additions = 0, deletions = 0 } of changes) {
271
+ const entry = files.get(path) || { count: 0, additions: 0, deletions: 0 };
272
+ entry.count += 1;
273
+ entry.additions += additions;
274
+ entry.deletions += deletions;
275
+ files.set(path, entry);
276
+ }
277
+ return {
278
+ changes: changes.length,
279
+ additions: [...files.values()].reduce((sum, entry) => sum + entry.additions, 0),
280
+ deletions: [...files.values()].reduce((sum, entry) => sum + entry.deletions, 0),
281
+ files: [...files].map(
282
+ ([path, entry]) =>
283
+ `${path}: ${entry.count} ${entry.count === 1 ? 'change' : 'changes'} +${entry.additions} -${entry.deletions}`
284
+ ),
285
+ };
286
+ }
287
+
186
288
  // A provider sometimes delivers the whole command as one quoted scalar
187
289
  // (`"git diff"`). That tokenizes to a single argument, so the git prefix check
188
290
  // rejected it and the caller paid a failed call plus a retry for a command it
@@ -351,14 +453,16 @@ function succeeded(result) {
351
453
 
352
454
  // `git grep` exits 1 for no match and `git diff --exit-code/--quiet/--check`
353
455
  // exits 1 to report a difference; the shell tool marks the same exits as
354
- // signals, so the git tool does too.
456
+ // signals, so the git tool does too. `git merge-tree` exits 1 with its report
457
+ // on stdout when the merge has conflicts. Returns the outcome name or null.
355
458
  function exitSignal(plan, result) {
356
- if (result.exitCode !== 1 || String(result.stderr || '').trim()) return false;
357
- if (plan.operation === 'grep') return true;
358
- if (plan.operation !== 'diff') return false;
459
+ if (result.exitCode !== 1 || visibleStderr(result.stderr).trim()) return null;
460
+ if (plan.operation === 'grep') return 'no-match';
461
+ if (plan.operation === 'merge-tree') return String(result.stdout || '').trim() ? 'conflicts' : null;
462
+ if (plan.operation !== 'diff') return null;
359
463
  const separator = plan.args.indexOf('--');
360
464
  const options = separator === -1 ? plan.args : plan.args.slice(0, separator);
361
- return options.some((arg) => GIT_DIFF_EXIT_SIGNAL_FLAGS.has(arg));
465
+ return options.some((arg) => GIT_DIFF_EXIT_SIGNAL_FLAGS.has(arg)) ? 'no-match' : null;
362
466
  }
363
467
 
364
468
  // ENOENT from the spawn itself is a capability fact, not a git error: the
@@ -690,10 +794,7 @@ async function executeGitStage(input, workDir, options = {}) {
690
794
  if (!succeeded(applied)) return commandFailure(applyPlan, applied, limit);
691
795
  deleteDiffSnapshot(request.diffId);
692
796
  invalidateAfterGitMutation();
693
- return ok({
694
- staged: true,
695
- changes: built.changes.map(({ id, preview, ...change }) => change),
696
- });
797
+ return ok({ staged: true, ...stagedSummary(built.changes) });
697
798
  });
698
799
  }),
699
800
  { signal }
@@ -703,7 +804,13 @@ async function executeGitStage(input, workDir, options = {}) {
703
804
  async function executeSingleGitTool(input, workDir, options = {}) {
704
805
  if (!input || typeof input !== 'object' || Array.isArray(input)) return rejected('git requires an arguments object');
705
806
  const hasCommand = typeof input.command === 'string' && Boolean(input.command.trim());
706
- if (!hasCommand) return rejected('git requires command');
807
+ if (!hasCommand) {
808
+ return rejected(
809
+ input.include_stage_ids === true
810
+ ? 'git requires command; staging IDs come from command:"git diff" (or "git diff -- <paths>") with include_stage_ids:true'
811
+ : 'git requires command: a full command starting with git, e.g. command:"git status"'
812
+ );
813
+ }
707
814
  let plan;
708
815
  try {
709
816
  plan = localizeConfigPlan(parseCommand(input.command, workDir));
@@ -717,7 +824,10 @@ async function executeSingleGitTool(input, workDir, options = {}) {
717
824
  return rejected('git archive requires -o/--output; binary stdout is not returned');
718
825
  }
719
826
  const limitDefault = plan.operation === 'log' ? 10 : 50;
720
- const limit = outputLimit(input.output_limit, limitDefault);
827
+ const limit = {
828
+ lines: outputLimit(input.output_limit, limitDefault),
829
+ chars: options.charBudget ?? COMMAND_CHAR_BUDGET,
830
+ };
721
831
  const signal = abortSignalOf(options);
722
832
  if (plan.operation === 'init' || plan.operation === 'clone') {
723
833
  const target = creationTarget(plan);
@@ -870,13 +980,14 @@ export async function executeGitTool(rawInput, workDir, options = {}) {
870
980
  return fail(`git command array requires 1 to ${GIT_COMMAND_ARRAY_LIMIT} commands`);
871
981
  }
872
982
 
983
+ const operations = [];
873
984
  for (let index = 0; index < commands.length; index += 1) {
874
985
  const command = commands[index];
875
986
  if (typeof command !== 'string' || !command.trim()) {
876
987
  return fail(`git command ${index + 1} must be a non-empty string`);
877
988
  }
878
989
  try {
879
- localizeConfigPlan(parseCommand(command, workDir));
990
+ operations.push(localizeConfigPlan(parseCommand(command, workDir)).operation);
880
991
  } catch (error) {
881
992
  return fail(`git command ${index + 1}: ${error.message}`);
882
993
  }
@@ -887,12 +998,22 @@ export async function executeGitTool(rawInput, workDir, options = {}) {
887
998
  // not produce. Every command is parsed above before any runs, so a typo in
888
999
  // command 3 never leaves commands 1-2 half applied. Each command still
889
1000
  // acquires its own repository lock inside executeSingleGitTool.
1001
+ // Headers name the position and subcommand only: echoing the argument list
1002
+ // (a 22-path `add`) cost more than the result it labelled.
890
1003
  const results = [];
891
- for (const command of commands) {
892
- const result = await executeSingleGitTool({ ...input, command }, workDir, options);
893
- results.push(`## ${command}\n${result.text}`);
1004
+ let used = 0;
1005
+ for (let index = 0; index < commands.length; index += 1) {
1006
+ const label = `${index + 1}: git ${operations[index]}`;
1007
+ const charBudget = Math.min(COMMAND_CHAR_BUDGET, Math.max(MIN_COMMAND_CHARS, ARRAY_CHAR_BUDGET - used));
1008
+ const result = await executeSingleGitTool({ ...input, command: commands[index] }, workDir, {
1009
+ ...options,
1010
+ charBudget,
1011
+ });
1012
+ const section = `## ${label}\n${result.text}`;
1013
+ used += section.length;
1014
+ results.push(section);
894
1015
  if (result.failed) {
895
- return appendText(results.join('\n'), `error: command failed: ${command}`);
1016
+ return appendText(results.join('\n'), `error: command failed: ${label}`);
896
1017
  }
897
1018
  }
898
1019
  return results.join('\n');
@@ -104,14 +104,19 @@ function parseFiles(raw) {
104
104
  return files;
105
105
  }
106
106
 
107
+ // Change ids are ordinals (c1, c2, …) in diff order. They are only meaningful
108
+ // together with the diff_id they were listed under: staging first verifies the
109
+ // working diff still hashes to that snapshot, so an ordinal can never address a
110
+ // different change than the one the model saw.
107
111
  function annotateChanges(files) {
108
112
  const changes = [];
113
+ let ordinal = 0;
109
114
  for (const file of files) {
110
115
  if (!file.stageable) continue;
111
116
  if (file.kind) {
112
117
  const entries = file.hunks.flatMap((hunk) => hunk.entries);
113
118
  changes.push({
114
- id: `chg_${digest(file.lines.join('\n')).slice(0, 16)}`,
119
+ id: `c${++ordinal}`,
115
120
  path: file.path,
116
121
  kind: file.kind,
117
122
  additions: entries.filter(({ line }) => line.startsWith('+')).length,
@@ -126,9 +131,7 @@ function annotateChanges(files) {
126
131
  let group = null;
127
132
  const finishGroup = () => {
128
133
  if (!group) return;
129
- const id = `chg_${digest(
130
- [file.path, hunkIndex, group.oldStart, group.newStart, group.lines.join('\n')].join('\0')
131
- ).slice(0, 16)}`;
134
+ const id = `c${++ordinal}`;
132
135
  for (const entry of group.entries) entry.changeId = id;
133
136
  changes.push({
134
137
  id,
@@ -137,7 +140,6 @@ function annotateChanges(files) {
137
140
  new_start: group.newStart,
138
141
  additions: group.additions,
139
142
  deletions: group.deletions,
140
- preview: group.lines.slice(0, 4).map((line) => (line.length <= 180 ? line : `${line.slice(0, 180)}…`)),
141
143
  });
142
144
  group = null;
143
145
  };
@@ -9,7 +9,7 @@ export function splitGrepLineNumberOnlyPrefix(line) {
9
9
  };
10
10
  }
11
11
 
12
- export function splitGrepLinePrefix(line) {
12
+ export function splitGrepLinePrefix(line, matchOnly = false) {
13
13
  const text = String(line || '');
14
14
  if (!text) return null;
15
15
  const searchFrom = /^[A-Za-z]:/.test(text) ? 2 : 0;
@@ -19,7 +19,9 @@ export function splitGrepLinePrefix(line) {
19
19
  // Caller context decides whether line-number-only output is possible. A
20
20
  // relative path may itself start with digits + '-' (e.g. `12-x\path.txt`),
21
21
  // so this parser must not reject `^\d+[:\-]` by shape alone.
22
- const delim = text.slice(searchFrom).match(/([:-])(\d+)\1/);
22
+ // `matchOnly`: the caller ran rg without context lines, so only `:N:` is a
23
+ // delimiter and a `-N-` segment belongs to the filename (`config-12-a.txt`).
24
+ const delim = text.slice(searchFrom).match(matchOnly ? /(:)(\d+):/ : /([:-])(\d+)\1/);
23
25
  if (!delim) return null;
24
26
  const pathEnd = searchFrom + delim.index;
25
27
  if (pathEnd <= 0) return null;
@@ -68,7 +70,13 @@ export function parseGrepContextHeader(line) {
68
70
  };
69
71
  }
70
72
 
71
- export function normalizeGrepLine(line, pathOnly = false, outputMode = 'content', filenameOmitted = false) {
73
+ export function normalizeGrepLine(
74
+ line,
75
+ pathOnly = false,
76
+ outputMode = 'content',
77
+ filenameOmitted = false,
78
+ matchOnly = false
79
+ ) {
72
80
  if (process.platform !== 'win32') return line;
73
81
  // files_with_matches mode: the WHOLE line is a path, so every separator is
74
82
  // a path separator and a full `\`->`/` normalisation is correct.
@@ -79,7 +87,7 @@ export function normalizeGrepLine(line, pathOnly = false, outputMode = 'content'
79
87
  // There is no path prefix to normalise; everything after ^\d+[:\-] is
80
88
  // source content and must remain byte-exact.
81
89
  if (filenameOmitted && splitGrepLineNumberOnlyPrefix(line)) return line;
82
- const split = splitGrepLinePrefix(line);
90
+ const split = splitGrepLinePrefix(line, matchOnly);
83
91
  if (split) {
84
92
  return line.slice(0, split.pathEnd).replace(/\\/g, '/') + line.slice(split.pathEnd);
85
93
  }
@@ -99,7 +107,8 @@ export function normalizeGrepLine(line, pathOnly = false, outputMode = 'content'
99
107
  function parseGrepContentLine(line) {
100
108
  const text = String(line || '');
101
109
  if (!text || text === '--' || text.startsWith('... [')) return null;
102
- const split = splitGrepLinePrefix(text);
110
+ // Grouping only runs on context-free content output.
111
+ const split = splitGrepLinePrefix(text, true);
103
112
  if (split?.delimiter !== ':') return null;
104
113
  const content = text.slice(split.markerEnd);
105
114
  return { path: split.path, lineNo: split.lineNo, content };
@@ -75,10 +75,11 @@ function parseAnchor(line, { workDir, rgSpawnCwd, grepResolvedPath, searchPath,
75
75
  content: String(line).slice(split.markerEnd),
76
76
  };
77
77
  }
78
- const raw = splitGrepLinePrefix(line);
78
+ // The anchor pass runs rg without context lines: every line is a match.
79
+ const raw = splitGrepLinePrefix(line, true);
79
80
  if (raw?.delimiter !== ':') return null;
80
- const normalized = relativeGrepLine(line, workDir, false, outputMode, false);
81
- const display = splitGrepLinePrefix(normalized);
81
+ const normalized = relativeGrepLine(line, workDir, false, outputMode, false, true);
82
+ const display = splitGrepLinePrefix(normalized, true);
82
83
  if (display?.delimiter !== ':') return null;
83
84
  return {
84
85
  path: display.path,
@@ -301,8 +301,9 @@ export function formatGrepOutput({
301
301
  includeMatchCount = false,
302
302
  }) {
303
303
  const lines = headLimit === Infinity ? windowed : windowed.slice(0, headLimit);
304
+ const matchOnly = outputMode === 'content' && !(beforeN > 0 || afterN > 0 || contextN > 0);
304
305
  const normalized = lines.map((line) =>
305
- relativeGrepLine(line, workDir, outputMode === 'files_with_matches', outputMode, filenameOmitted)
306
+ relativeGrepLine(line, workDir, outputMode === 'files_with_matches', outputMode, filenameOmitted, matchOnly)
306
307
  );
307
308
  const remaining = Math.max(0, totalWindowed - lines.length);
308
309
  const shown = lines.length;
@@ -82,23 +82,25 @@ function combinedPathRequest(args, defaultHeadLimit) {
82
82
  // order; null when one is a glob, unreachable, or on a share — the legacy
83
83
  // fan-out owns those diagnostics.
84
84
  async function resolvePathRoots(list, workDir) {
85
- const roots = await Promise.all(list.map(async (p) => {
86
- const cleaned = normalizeInputPath(p);
87
- if (hasGlobMagic(cleaned)) return null;
88
- const resolved = resolveSearchScope(cleaned, workDir);
89
- if (isUncOrSmbPath(cleaned) || isUncOrSmbPath(resolved)) return null;
90
- let st;
91
- try {
92
- st = await statReachable(resolved);
93
- } catch {
94
- return null;
95
- }
96
- return {
97
- arg: p,
98
- abs: normalizeOutputPath(isAbsolute(resolved) ? await trueCasePath(resolved) : resolved),
99
- isDir: st.isDirectory(),
100
- };
101
- }));
85
+ const roots = await Promise.all(
86
+ list.map(async (p) => {
87
+ const cleaned = normalizeInputPath(p);
88
+ if (hasGlobMagic(cleaned)) return null;
89
+ const resolved = resolveSearchScope(cleaned, workDir);
90
+ if (isUncOrSmbPath(cleaned) || isUncOrSmbPath(resolved)) return null;
91
+ let st;
92
+ try {
93
+ st = await statReachable(resolved);
94
+ } catch {
95
+ return null;
96
+ }
97
+ return {
98
+ arg: p,
99
+ abs: normalizeOutputPath(isAbsolute(resolved) ? await trueCasePath(resolved) : resolved),
100
+ isDir: st.isDirectory(),
101
+ };
102
+ })
103
+ );
102
104
  if (roots.some((root) => !root)) return null;
103
105
  // An overlapping operand would scan a file twice and then attribute both
104
106
  // copies to each containing section. Keep independent scope semantics.
@@ -123,7 +125,7 @@ function attributeLinesToRoots(lines, roots, wdFwd) {
123
125
  for (const line of lines) {
124
126
  const norm = line.replace(/\\/g, '/');
125
127
  const lineKey = pathKey(norm);
126
- const rel = lineKey.startsWith(workDirKey) ? norm.slice(wdFwd.length + 1) : line;
128
+ const rel = lineKey.startsWith(workDirKey) ? line.slice(wdFwd.length + 1) : line;
127
129
  for (let i = 0; i < roots.length; i++) {
128
130
  const rootKey = pathKey(roots[i].abs);
129
131
  if (lineKey === rootKey || lineKey.startsWith(`${rootKey}/`) || lineKey.startsWith(`${rootKey}:`)) {
@@ -143,7 +145,7 @@ function renderedRootLines(root, windowedLines, wdFwd) {
143
145
  const rootPrefix = `${pathKey(rootRel)}:`;
144
146
  return windowedLines.map((l) => {
145
147
  const lineFwd = l.replace(/\\/g, '/');
146
- return pathKey(lineFwd).startsWith(rootPrefix) ? lineFwd.slice(rootRel.length + 1) : l;
148
+ return pathKey(lineFwd).startsWith(rootPrefix) ? l.slice(rootRel.length + 1) : l;
147
149
  });
148
150
  }
149
151
 
@@ -151,13 +153,13 @@ async function combinedPathBody(request, root, linesFor, { workDir, wdFwd, optio
151
153
  const { pattern, outMode, headLimit, offset, contextN, autoContext, caseInsensitive } = request;
152
154
  if (outMode === 'content' && (autoContext || contextN > 0)) {
153
155
  const ctx = await expandGrepAnchorContextOutput({
154
- allLines: linesFor,
156
+ allLines: renderedRootLines(root, linesFor, wdFwd),
155
157
  workDir,
156
158
  rgSpawnCwd: wdFwd,
157
159
  grepResolvedPath: root.abs,
158
160
  searchPath: root.arg,
159
161
  outputMode: outMode,
160
- filenameOmitted: false,
162
+ filenameOmitted: !root.isDir,
161
163
  headLimit,
162
164
  offset,
163
165
  totalKnown: true,
@@ -229,29 +231,31 @@ async function runCombinedPathFanout({ args, list, workDir, options, callContext
229
231
 
230
232
  // One rg invocation over every root's files at once.
231
233
  async function combinedPathRgArgs(args, request, roots, workDir) {
232
- const perRoot = await Promise.all(roots.map(async (root) => {
233
- const scope = await resolveGrepScope({ ...args, path: root.arg }, workDir);
234
- if (scope.result !== undefined) return null;
235
- return buildGrepRgArgs({
236
- patterns: [request.pattern],
237
- includeNoise: args.include_noise === true,
238
- text: args.text === true,
239
- searchPath: isAbsolute(scope.searchPath) ? root.abs : scope.searchPath,
240
- // Match buildGrepScope: an explicit file operand wins over its glob.
241
- globPatterns: root.isDir ? scope.normalizedGlobPatterns : [],
242
- outputMode: request.outMode,
243
- caseInsensitive: request.caseInsensitive,
244
- showLineNumbers: true,
245
- beforeN: null,
246
- afterN: null,
247
- contextN: null,
248
- multilineMode: false,
249
- fileType: '',
250
- onlyMatching: false,
251
- pcre2: false,
252
- withFilename: true,
253
- }).slice(0, -1);
254
- }));
234
+ const perRoot = await Promise.all(
235
+ roots.map(async (root) => {
236
+ const scope = await resolveGrepScope({ ...args, path: root.arg }, workDir);
237
+ if (scope.result !== undefined) return null;
238
+ return buildGrepRgArgs({
239
+ patterns: [request.pattern],
240
+ includeNoise: args.include_noise === true,
241
+ text: args.text === true,
242
+ searchPath: isAbsolute(scope.searchPath) ? root.abs : scope.searchPath,
243
+ // Match buildGrepScope: an explicit file operand wins over its glob.
244
+ globPatterns: root.isDir ? scope.normalizedGlobPatterns : [],
245
+ outputMode: request.outMode,
246
+ caseInsensitive: request.caseInsensitive,
247
+ showLineNumbers: true,
248
+ beforeN: null,
249
+ afterN: null,
250
+ contextN: null,
251
+ multilineMode: false,
252
+ fileType: '',
253
+ onlyMatching: false,
254
+ pcre2: false,
255
+ withFilename: true,
256
+ }).slice(0, -1);
257
+ })
258
+ );
255
259
  if (perRoot.some((argv) => !argv)) return null;
256
260
  const first = JSON.stringify(perRoot[0]);
257
261
  // Native filters are rooted at each operand. Only identical normalized
@@ -3,12 +3,19 @@ import { canonicalizeGlobSlashes } from '../path-utils.mjs';
3
3
  import { relativePathPrefix } from '../search-path-diagnostics.mjs';
4
4
  import { normalizeGrepLine, splitGrepCountPrefix, splitGrepLinePrefix } from '../grep-formatting.mjs';
5
5
 
6
- export function relativeGrepLine(line, workDir, pathOnly = false, outputMode = 'content', filenameOmitted = false) {
7
- const normalized = normalizeGrepLine(line, pathOnly, outputMode, filenameOmitted);
6
+ export function relativeGrepLine(
7
+ line,
8
+ workDir,
9
+ pathOnly = false,
10
+ outputMode = 'content',
11
+ filenameOmitted = false,
12
+ matchOnly = false
13
+ ) {
14
+ const normalized = normalizeGrepLine(line, pathOnly, outputMode, filenameOmitted, matchOnly);
8
15
  if (!workDir) return normalized;
9
16
  if (pathOnly) return relativePathPrefix(normalized, workDir);
10
17
  if (filenameOmitted) return normalized;
11
- const split = splitGrepLinePrefix(normalized);
18
+ const split = splitGrepLinePrefix(normalized, matchOnly);
12
19
  if (split) {
13
20
  return relativePathPrefix(normalized.slice(0, split.pathEnd), workDir) + normalized.slice(split.pathEnd);
14
21
  }