@stigmer/runner 3.15.3-dev.20260914100347 → 3.15.3-dev.20260916211208

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 (549) hide show
  1. package/README.md +1 -0
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/approval-contract/types.d.ts +1 -1
  4. package/dist/__test-utils__/hermetic-activity.d.ts +61 -7
  5. package/dist/__test-utils__/hermetic-activity.js +100 -9
  6. package/dist/__test-utils__/hermetic-activity.js.map +1 -1
  7. package/dist/__test-utils__/model-registry-fixture.d.ts +22 -3
  8. package/dist/__test-utils__/model-registry-fixture.js +22 -7
  9. package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
  10. package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +2 -2
  11. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +14 -11
  12. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
  13. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
  14. package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
  15. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
  16. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
  17. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  18. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +52 -14
  19. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +46 -12
  20. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  21. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +21 -28
  22. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +27 -11
  23. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
  24. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +70 -26
  25. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +82 -32
  26. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -1
  27. package/dist/activities/execute-cursor/adapter.d.ts +8 -7
  28. package/dist/activities/execute-cursor/adapter.js +13 -9
  29. package/dist/activities/execute-cursor/adapter.js.map +1 -1
  30. package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
  31. package/dist/activities/execute-cursor/approval-policy.js +12 -23
  32. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  33. package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
  34. package/dist/activities/execute-cursor/approval-state.js +65 -0
  35. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  36. package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
  37. package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
  38. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
  39. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
  40. package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
  41. package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
  42. package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
  43. package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
  44. package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
  45. package/dist/activities/execute-cursor/prompt-builder.js +4 -4
  46. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  47. package/dist/activities/execute-cursor/sdk-warmup.d.ts +15 -6
  48. package/dist/activities/execute-cursor/sdk-warmup.js +15 -6
  49. package/dist/activities/execute-cursor/sdk-warmup.js.map +1 -1
  50. package/dist/activities/execute-cursor/service-tier.js +1 -2
  51. package/dist/activities/execute-cursor/service-tier.js.map +1 -1
  52. package/dist/activities/execute-cursor/session-lifecycle.d.ts +38 -59
  53. package/dist/activities/execute-cursor/session-lifecycle.js +59 -96
  54. package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
  55. package/dist/activities/execute-cursor/session-store.d.ts +100 -0
  56. package/dist/activities/execute-cursor/session-store.js +157 -0
  57. package/dist/activities/execute-cursor/session-store.js.map +1 -0
  58. package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
  59. package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
  60. package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
  61. package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
  62. package/dist/activities/execute-cursor/tool-result.js +130 -0
  63. package/dist/activities/execute-cursor/tool-result.js.map +1 -0
  64. package/dist/activities/execute-cursor/translator.d.ts +178 -0
  65. package/dist/activities/execute-cursor/translator.js +485 -0
  66. package/dist/activities/execute-cursor/translator.js.map +1 -0
  67. package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
  68. package/dist/activities/execute-cursor/turn-boundary.js +10 -14
  69. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  70. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  71. package/dist/activities/execute-cursor/turn-settle.js +47 -34
  72. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  73. package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
  74. package/dist/activities/execute-cursor/turn-setup.js +5 -5
  75. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  76. package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
  77. package/dist/activities/execute-cursor/turn-stream.js +41 -28
  78. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  79. package/dist/activities/execute-cursor/turn.d.ts +4 -4
  80. package/dist/activities/execute-cursor/turn.js +5 -5
  81. package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
  82. package/dist/activities/execute-cursor/usage-pricing.js +2 -2
  83. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
  84. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
  85. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
  86. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
  87. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  88. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
  89. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
  91. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
  92. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
  93. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
  94. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
  95. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
  97. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
  98. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
  99. package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
  100. package/dist/activities/execute-deep-agent/adapter.js +1 -1
  101. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
  102. package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
  103. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
  104. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
  105. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
  106. package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
  107. package/dist/activities/execute-deep-agent/hitl.js +2 -2
  108. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
  109. package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
  110. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
  112. package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
  113. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  114. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
  115. package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
  116. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  117. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
  118. package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
  119. package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
  120. package/dist/activities/execute-deep-agent/translator.js +418 -0
  121. package/dist/activities/execute-deep-agent/translator.js.map +1 -0
  122. package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
  123. package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
  124. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  125. package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
  126. package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
  127. package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
  128. package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
  129. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  130. package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
  131. package/dist/activities/execute-deep-agent/turn.js +3 -3
  132. package/dist/config.d.ts +2 -2
  133. package/dist/harness/approval-decisions.d.ts +1 -1
  134. package/dist/harness/approval-decisions.js +1 -1
  135. package/dist/harness/capabilities.d.ts +21 -11
  136. package/dist/harness/capabilities.js +2 -2
  137. package/dist/harness/capture.d.ts +4 -4
  138. package/dist/harness/capture.js +4 -4
  139. package/dist/harness/persist-chokepoint.d.ts +3 -3
  140. package/dist/harness/persist-chokepoint.js +3 -3
  141. package/dist/harness/registry.d.ts +2 -2
  142. package/dist/harness/registry.js +2 -2
  143. package/dist/harness/run-turn.d.ts +6 -4
  144. package/dist/harness/run-turn.js +31 -9
  145. package/dist/harness/run-turn.js.map +1 -1
  146. package/dist/harness/stop-controller.d.ts +1 -1
  147. package/dist/harness/stop-controller.js +1 -1
  148. package/dist/harness/terminal-table.d.ts +7 -7
  149. package/dist/harness/terminal-table.js +7 -7
  150. package/dist/harness/transcript/builder.d.ts +182 -0
  151. package/dist/harness/transcript/builder.js +693 -0
  152. package/dist/harness/transcript/builder.js.map +1 -0
  153. package/dist/harness/transcript/events.d.ts +218 -0
  154. package/dist/harness/transcript/events.js +50 -0
  155. package/dist/harness/transcript/events.js.map +1 -0
  156. package/dist/harness/transcript/state.d.ts +110 -0
  157. package/dist/harness/transcript/state.js +148 -0
  158. package/dist/harness/transcript/state.js.map +1 -0
  159. package/dist/harness/turn-context.d.ts +54 -38
  160. package/dist/harness/turn-context.js +42 -43
  161. package/dist/harness/turn-context.js.map +1 -1
  162. package/dist/harness/types.d.ts +63 -22
  163. package/dist/harness/types.js +12 -11
  164. package/dist/harness/types.js.map +1 -1
  165. package/dist/harness/usage-accumulator.d.ts +2 -2
  166. package/dist/harness/usage-accumulator.js +2 -2
  167. package/dist/harness-adapters.d.ts +5 -4
  168. package/dist/harness-adapters.js +5 -4
  169. package/dist/harness-adapters.js.map +1 -1
  170. package/dist/middleware/approval-gate.d.ts +6 -0
  171. package/dist/middleware/approval-gate.js +7 -57
  172. package/dist/middleware/approval-gate.js.map +1 -1
  173. package/dist/middleware/cost-advisory.d.ts +3 -3
  174. package/dist/middleware/cost-advisory.js +3 -3
  175. package/dist/middleware/index.d.ts +1 -1
  176. package/dist/middleware/index.js +1 -1
  177. package/dist/runner-manager.js +1 -1
  178. package/dist/runner-manager.js.map +1 -1
  179. package/dist/shared/approval-policy.d.ts +53 -0
  180. package/dist/shared/approval-policy.js +76 -0
  181. package/dist/shared/approval-policy.js.map +1 -1
  182. package/dist/shared/args-preview.d.ts +45 -22
  183. package/dist/shared/args-preview.js +51 -41
  184. package/dist/shared/args-preview.js.map +1 -1
  185. package/dist/shared/attachment-resolver.d.ts +4 -4
  186. package/dist/shared/attachment-resolver.js +4 -4
  187. package/dist/shared/attachment-vision.d.ts +2 -1
  188. package/dist/shared/attachment-vision.js.map +1 -1
  189. package/dist/shared/attachment-zip.d.ts +2 -2
  190. package/dist/shared/attachment-zip.js +2 -2
  191. package/dist/shared/cost-guard.d.ts +2 -2
  192. package/dist/shared/cost-guard.js +2 -2
  193. package/dist/shared/exact-apply.d.ts +1 -1
  194. package/dist/shared/exact-apply.js +1 -1
  195. package/dist/shared/execution-context.d.ts +2 -2
  196. package/dist/shared/execution-context.js +2 -2
  197. package/dist/shared/extract-structured-output.d.ts +2 -2
  198. package/dist/shared/extract-structured-output.js +2 -2
  199. package/dist/shared/filereview/cas-touched.d.ts +2 -2
  200. package/dist/shared/filereview/cas-touched.js +2 -2
  201. package/dist/shared/heartbeat.d.ts +1 -1
  202. package/dist/shared/heartbeat.js +1 -1
  203. package/dist/shared/llm-backend.d.ts +0 -4
  204. package/dist/shared/llm-backend.js +0 -4
  205. package/dist/shared/llm-backend.js.map +1 -1
  206. package/dist/shared/model-error.d.ts +1 -2
  207. package/dist/shared/model-error.js +1 -2
  208. package/dist/shared/model-error.js.map +1 -1
  209. package/dist/shared/persist-decision.d.ts +18 -24
  210. package/dist/shared/persist-decision.js +19 -11
  211. package/dist/shared/persist-decision.js.map +1 -1
  212. package/dist/shared/prompt-sections.d.ts +4 -4
  213. package/dist/shared/prompt-sections.js +4 -4
  214. package/dist/shared/skill-resolver.d.ts +3 -3
  215. package/dist/shared/skill-resolver.js +3 -3
  216. package/dist/shared/status-offload.d.ts +1 -1
  217. package/dist/shared/status-offload.js +2 -2
  218. package/dist/shared/status-offload.js.map +1 -1
  219. package/dist/shared/streaming-scheduler.d.ts +2 -7
  220. package/dist/shared/streaming-scheduler.js +6 -14
  221. package/dist/shared/streaming-scheduler.js.map +1 -1
  222. package/dist/shared/subagent-rows.d.ts +2 -2
  223. package/dist/shared/subagent-rows.js +2 -2
  224. package/dist/shared/todos.d.ts +3 -3
  225. package/dist/shared/todos.js +3 -3
  226. package/dist/shared/tool-row.d.ts +19 -1
  227. package/dist/shared/tool-row.js +36 -2
  228. package/dist/shared/tool-row.js.map +1 -1
  229. package/dist/shared/worker-shutdown.d.ts +1 -1
  230. package/dist/shared/worker-shutdown.js +1 -1
  231. package/dist/shared/workspace/session-provision.d.ts +1 -1
  232. package/dist/shared/workspace/session-provision.js +1 -1
  233. package/dist/shared/workspace/sources/empty.d.ts +1 -1
  234. package/dist/shared/workspace/sources/empty.js +1 -2
  235. package/dist/shared/workspace/sources/empty.js.map +1 -1
  236. package/dist/shared/workspace/sources/git.js +4 -4
  237. package/dist/shared/workspace/sources/git.js.map +1 -1
  238. package/dist/shared/workspace/sources/local-path.js +6 -6
  239. package/dist/shared/workspace/sources/local-path.js.map +1 -1
  240. package/dist/shared/workspace/stigmer-link.d.ts +1 -1
  241. package/dist/shared/workspace/stigmer-link.js +1 -1
  242. package/dist/shared/workspace/types.d.ts +2 -5
  243. package/dist/shared/workspace/types.js +0 -6
  244. package/dist/shared/workspace/types.js.map +1 -1
  245. package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
  246. package/dist/shared/workspace/writeback-coordinator.js +7 -9
  247. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  248. package/package.json +5 -5
  249. package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
  250. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
  251. package/src/__test-utils__/approval-contract/contract.ts +1 -1
  252. package/src/__test-utils__/approval-contract/types.ts +1 -1
  253. package/src/__test-utils__/harness-boot-order-child.ts +1 -1
  254. package/src/__test-utils__/harness-contract/contract.ts +8 -8
  255. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  256. package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
  257. package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
  258. package/src/__test-utils__/hermetic-activity.ts +113 -9
  259. package/src/__test-utils__/model-registry-fixture.ts +31 -7
  260. package/src/__test-utils__/module-specifiers.ts +32 -3
  261. package/src/__tests__/harness-boot-order.test.ts +1 -1
  262. package/src/__tests__/harness-contract.test.ts +1 -1
  263. package/src/__tests__/runner-manager.test.ts +1 -1
  264. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +32 -8
  265. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +12 -10
  266. package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
  267. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
  268. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +72 -19
  269. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +35 -29
  270. package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +94 -38
  271. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
  272. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
  273. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
  274. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
  275. package/src/activities/execute-cursor/__tests__/cursor-baseurl-routing.test.ts +10 -8
  276. package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
  277. package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +24 -12
  278. package/src/activities/execute-cursor/__tests__/cursor-generate-image-live.test.ts +7 -2
  279. package/src/activities/execute-cursor/__tests__/cursor-hook-protocol-live.test.ts +163 -0
  280. package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +23 -20
  281. package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
  282. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
  283. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
  284. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +5 -2
  285. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -2
  286. package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
  287. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
  288. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
  289. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
  290. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
  291. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
  292. package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
  293. package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
  294. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
  295. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
  296. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
  297. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +10 -7
  298. package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
  299. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +8 -5
  300. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +6 -2
  301. package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +4 -1
  302. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +6 -2
  303. package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
  304. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
  305. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +12 -9
  306. package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
  307. package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
  308. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +4 -1
  309. package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
  310. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +7 -4
  311. package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
  312. package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
  313. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +17 -2
  314. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -2
  315. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
  316. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
  317. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
  318. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
  319. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
  320. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
  321. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
  322. package/src/activities/execute-cursor/__tests__/session-lifecycle.test.ts +86 -58
  323. package/src/activities/execute-cursor/__tests__/session-store.test.ts +220 -0
  324. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
  325. package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
  326. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
  327. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
  328. package/src/activities/execute-cursor/adapter.ts +13 -9
  329. package/src/activities/execute-cursor/approval-policy.ts +12 -24
  330. package/src/activities/execute-cursor/approval-state.ts +66 -1
  331. package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
  332. package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
  333. package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
  334. package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
  335. package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
  336. package/src/activities/execute-cursor/prompt-builder.ts +6 -6
  337. package/src/activities/execute-cursor/sdk-warmup.ts +15 -6
  338. package/src/activities/execute-cursor/service-tier.ts +1 -2
  339. package/src/activities/execute-cursor/session-lifecycle.ts +63 -109
  340. package/src/activities/execute-cursor/session-store.ts +187 -0
  341. package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
  342. package/src/activities/execute-cursor/tool-result.ts +128 -0
  343. package/src/activities/execute-cursor/translator.ts +541 -0
  344. package/src/activities/execute-cursor/turn-boundary.ts +21 -14
  345. package/src/activities/execute-cursor/turn-settle.ts +46 -34
  346. package/src/activities/execute-cursor/turn-setup.ts +5 -5
  347. package/src/activities/execute-cursor/turn-stream.ts +49 -46
  348. package/src/activities/execute-cursor/turn.ts +5 -5
  349. package/src/activities/execute-cursor/usage-pricing.ts +2 -2
  350. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
  351. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
  352. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
  353. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
  354. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
  355. package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
  356. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
  357. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
  358. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
  359. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
  360. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
  361. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
  362. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
  363. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
  364. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
  365. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
  366. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
  367. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
  368. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
  369. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
  370. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
  371. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
  372. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
  373. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
  374. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
  375. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
  376. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
  377. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
  378. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
  379. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
  380. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
  381. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
  382. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
  383. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
  384. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
  385. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
  386. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
  387. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
  388. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
  389. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
  390. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
  391. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
  392. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
  393. package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
  394. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
  395. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
  396. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
  397. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
  398. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
  399. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
  400. package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
  401. package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
  402. package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
  403. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
  404. package/src/activities/execute-deep-agent/adapter.ts +1 -1
  405. package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
  406. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
  407. package/src/activities/execute-deep-agent/hitl.ts +2 -2
  408. package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
  409. package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
  410. package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
  411. package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
  412. package/src/activities/execute-deep-agent/translator.ts +463 -0
  413. package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
  414. package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
  415. package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
  416. package/src/activities/execute-deep-agent/turn.ts +3 -3
  417. package/src/config.ts +2 -2
  418. package/src/harness/README.md +335 -0
  419. package/src/harness/__tests__/approval-decisions.test.ts +2 -2
  420. package/src/harness/__tests__/capture.test.ts +3 -3
  421. package/src/harness/__tests__/import-direction.test.ts +3 -2
  422. package/src/harness/__tests__/mount-skills.test.ts +4 -1
  423. package/src/harness/__tests__/readme-index.test.ts +339 -0
  424. package/src/harness/__tests__/run-turn.test.ts +131 -6
  425. package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
  426. package/src/harness/__tests__/transcript-writers.test.ts +191 -0
  427. package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
  428. package/src/harness/__tests__/turn-context.test.ts +5 -5
  429. package/src/harness/approval-decisions.ts +1 -1
  430. package/src/harness/capabilities.ts +21 -11
  431. package/src/harness/capture.ts +4 -4
  432. package/src/harness/persist-chokepoint.ts +3 -3
  433. package/src/harness/registry.ts +2 -2
  434. package/src/harness/run-turn.ts +33 -9
  435. package/src/harness/stop-controller.ts +1 -1
  436. package/src/harness/terminal-table.ts +7 -7
  437. package/src/harness/transcript/__tests__/builder.test.ts +975 -0
  438. package/src/harness/transcript/__tests__/state.test.ts +143 -0
  439. package/src/harness/transcript/builder.ts +755 -0
  440. package/src/harness/transcript/events.ts +262 -0
  441. package/src/harness/transcript/state.ts +167 -0
  442. package/src/harness/turn-context.ts +61 -46
  443. package/src/harness/types.ts +64 -22
  444. package/src/harness/usage-accumulator.ts +2 -2
  445. package/src/harness-adapters.ts +5 -4
  446. package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
  447. package/src/middleware/approval-gate.ts +7 -74
  448. package/src/middleware/cost-advisory.ts +3 -3
  449. package/src/middleware/index.ts +1 -1
  450. package/src/runner-manager.ts +1 -1
  451. package/src/shared/__tests__/approval-policy.test.ts +45 -0
  452. package/src/shared/__tests__/args-preview.test.ts +40 -20
  453. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  454. package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
  455. package/src/shared/__tests__/attachment-zip.test.ts +1 -1
  456. package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
  457. package/src/shared/__tests__/cost-guard.test.ts +1 -1
  458. package/src/shared/__tests__/exact-apply.test.ts +2 -1
  459. package/src/shared/__tests__/persist-decision.test.ts +19 -33
  460. package/src/shared/__tests__/prompt-sections.test.ts +1 -1
  461. package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
  462. package/src/shared/__tests__/status-offload.test.ts +1 -1
  463. package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
  464. package/src/shared/__tests__/todos.test.ts +1 -1
  465. package/src/shared/__tests__/tool-row.test.ts +1 -1
  466. package/src/shared/approval-policy.ts +95 -0
  467. package/src/shared/args-preview.ts +51 -42
  468. package/src/shared/attachment-resolver.ts +4 -4
  469. package/src/shared/attachment-vision.ts +2 -1
  470. package/src/shared/attachment-zip.ts +2 -2
  471. package/src/shared/cost-guard.ts +2 -2
  472. package/src/shared/exact-apply.ts +1 -1
  473. package/src/shared/execution-context.ts +2 -2
  474. package/src/shared/extract-structured-output.ts +2 -2
  475. package/src/shared/filereview/__tests__/capture.test.ts +9 -5
  476. package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
  477. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
  478. package/src/shared/filereview/cas-touched.ts +2 -2
  479. package/src/shared/heartbeat.ts +1 -1
  480. package/src/shared/llm-backend.ts +0 -4
  481. package/src/shared/model-error.ts +1 -2
  482. package/src/shared/persist-decision.ts +19 -28
  483. package/src/shared/prompt-sections.ts +4 -4
  484. package/src/shared/skill-resolver.ts +3 -3
  485. package/src/shared/status-offload.ts +2 -2
  486. package/src/shared/streaming-scheduler.ts +8 -13
  487. package/src/shared/subagent-rows.ts +2 -2
  488. package/src/shared/todos.ts +3 -3
  489. package/src/shared/tool-row.ts +38 -2
  490. package/src/shared/worker-shutdown.ts +1 -1
  491. package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
  492. package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
  493. package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
  494. package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
  495. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
  496. package/src/shared/workspace/provisioner.ts +1 -1
  497. package/src/shared/workspace/session-provision.ts +1 -1
  498. package/src/shared/workspace/sources/empty.ts +2 -2
  499. package/src/shared/workspace/sources/git.ts +3 -4
  500. package/src/shared/workspace/sources/local-path.ts +5 -6
  501. package/src/shared/workspace/stigmer-link.ts +1 -1
  502. package/src/shared/workspace/types.ts +2 -5
  503. package/src/shared/workspace/writeback-coordinator.ts +23 -12
  504. package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
  505. package/dist/activities/execute-cursor/delta-enricher.js +0 -265
  506. package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
  507. package/dist/activities/execute-cursor/message-translator.js +0 -2040
  508. package/dist/activities/execute-cursor/message-translator.js.map +0 -1
  509. package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
  510. package/dist/activities/execute-cursor/todo-tracker.js +0 -80
  511. package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
  512. package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
  513. package/dist/activities/execute-deep-agent/execution-state.js +0 -68
  514. package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
  515. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
  516. package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
  517. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
  518. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
  519. package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
  520. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
  521. package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
  522. package/dist/activities/execute-deep-agent/v3-events.js +0 -35
  523. package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
  524. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
  525. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
  526. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
  527. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
  528. package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
  529. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
  530. package/dist/shared/execution-status-writer.d.ts +0 -31
  531. package/dist/shared/execution-status-writer.js +0 -43
  532. package/dist/shared/execution-status-writer.js.map +0 -1
  533. package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
  534. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
  535. package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
  536. package/src/activities/execute-cursor/delta-enricher.ts +0 -307
  537. package/src/activities/execute-cursor/message-translator.ts +0 -2319
  538. package/src/activities/execute-cursor/todo-tracker.ts +0 -91
  539. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
  540. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
  541. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
  542. package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
  543. package/src/activities/execute-deep-agent/execution-state.ts +0 -78
  544. package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
  545. package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
  546. package/src/activities/execute-deep-agent/v3-events.ts +0 -153
  547. package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
  548. package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
  549. package/src/shared/execution-status-writer.ts +0 -56
@@ -0,0 +1,505 @@
1
+ /**
2
+ * The native translator's own arms (`execute-deep-agent/translator.ts`): one
3
+ * raw LangGraph v3 protocol event in, the `TranscriptEvent`s out. Two layers,
4
+ * tested apart: `normalize`, the stateless core that reads the wire's shape
5
+ * (root-scoped, unattributed), and `DeepAgentTranslator`, which lays scope
6
+ * and the gate's answers on top and speaks a sub-agent's lifecycle.
7
+ * Beside them, what `usageOf` reads off the same wire for the loop.
8
+ * The events the wire carries and the transcript does not
9
+ * (`lifecycle`, `provider`, the standalone `usage`) are pinned as producing
10
+ * NOTHING, so a member cannot creep back into the union unnoticed.
11
+ */
12
+
13
+ import { describe, it, expect, beforeEach } from "vitest";
14
+ import { DeepAgentTranslator, normalize, usageOf } from "../translator.js";
15
+ import {
16
+ resetSeq,
17
+ makeProtocolEvent,
18
+ makeMessageStart,
19
+ makeMessageFinish,
20
+ makeTextDelta,
21
+ makeReasoningDelta,
22
+ makeToolCallArgDelta,
23
+ makeToolStarted,
24
+ makeToolFinished,
25
+ makeToolError,
26
+ makeToolOutputDelta,
27
+ makeUsageEvent,
28
+ makeProviderEvent,
29
+ makeLifecycleRunning,
30
+ makeLifecycleCompleted,
31
+ makeContentBlockStartText,
32
+ makeContentBlockFinish,
33
+ makeCheckpointEvent,
34
+ makeTasksEvent,
35
+ makeValuesEvent,
36
+ makeUpdatesEvent,
37
+ } from "../__test-utils__/v3-event-fixtures.js";
38
+
39
+ beforeEach(() => resetSeq());
40
+
41
+ describe("V3ProtocolNormalizer", () => {
42
+
43
+ // ── Message channel ──────────────────────────────────────────────
44
+
45
+ describe("messages channel", () => {
46
+ it("normalizes message-start to the run id alone (the wire's message id is not a transcript fact)", () => {
47
+ const result = normalize(makeMessageStart("run-1", { messageId: "msg_abc" }));
48
+ expect(result).toHaveLength(1);
49
+ expect(result[0]).toEqual({ kind: "message_start", runId: "run-1" });
50
+ });
51
+
52
+ it("normalizes text-delta", () => {
53
+ const result = normalize(makeTextDelta("run-1", "Hello "));
54
+ expect(result).toHaveLength(1);
55
+ expect(result[0]).toMatchObject({
56
+ kind: "text_delta",
57
+ runId: "run-1",
58
+ text: "Hello ",
59
+ });
60
+ });
61
+
62
+ it("normalizes reasoning-delta", () => {
63
+ const result = normalize(makeReasoningDelta("run-1", "Let me think..."));
64
+ expect(result).toHaveLength(1);
65
+ expect(result[0]).toMatchObject({
66
+ kind: "reasoning_delta",
67
+ runId: "run-1",
68
+ text: "Let me think...",
69
+ });
70
+ });
71
+
72
+ it("normalizes tool_call_chunk via block-delta", () => {
73
+ const result = normalize(makeToolCallArgDelta("run-1", "toolu_123", '{"path":'));
74
+ expect(result).toHaveLength(1);
75
+ expect(result[0]).toMatchObject({
76
+ kind: "tool_arg_delta",
77
+ callId: "toolu_123",
78
+ argsChunk: '{"path":',
79
+ });
80
+ });
81
+
82
+ it("normalizes message-finish to the run id alone — its usage and reason are the loop's, not the transcript's", () => {
83
+ const result = normalize(makeMessageFinish("run-1", {
84
+ reason: "end_turn",
85
+ usage: { input_tokens: 100, output_tokens: 20, total_tokens: 120 },
86
+ }));
87
+ expect(result).toHaveLength(1);
88
+ expect(result[0]).toEqual({ kind: "message_finish", runId: "run-1" });
89
+ });
90
+
91
+ it("emits nothing for the standalone usage event", () => {
92
+ expect(normalize(makeUsageEvent("run-1", { input_tokens: 50, output_tokens: 10 }))).toHaveLength(0);
93
+ });
94
+
95
+ it("emits nothing for the provider event", () => {
96
+ expect(normalize(makeProviderEvent("run-1", "anthropic", "claude-sonnet-4-6"))).toHaveLength(0);
97
+ });
98
+
99
+ it("returns empty for content-block-start", () => {
100
+ const result = normalize(makeContentBlockStartText("run-1"));
101
+ expect(result).toHaveLength(0);
102
+ });
103
+
104
+ it("returns empty for content-block-finish", () => {
105
+ const result = normalize(makeContentBlockFinish("run-1"));
106
+ expect(result).toHaveLength(0);
107
+ });
108
+
109
+ it("ignores empty text-delta", () => {
110
+ const result = normalize(makeTextDelta("run-1", ""));
111
+ expect(result).toHaveLength(0);
112
+ });
113
+
114
+ it("ignores empty reasoning-delta", () => {
115
+ const result = normalize(makeReasoningDelta("run-1", ""));
116
+ expect(result).toHaveLength(0);
117
+ });
118
+ });
119
+
120
+ // ── Tools channel ────────────────────────────────────────────────
121
+
122
+ describe("tools channel", () => {
123
+ it("normalizes tool-started with snake_case fields", () => {
124
+ const result = normalize(makeToolStarted("toolu_abc", "read_file", '{"path":"/src/main.ts"}'));
125
+ expect(result).toHaveLength(1);
126
+ expect(result[0]).toMatchObject({
127
+ kind: "tool_started",
128
+ callId: "toolu_abc",
129
+ name: "read_file",
130
+ input: { path: "/src/main.ts" },
131
+ });
132
+ });
133
+
134
+ it("normalizes tool-started with camelCase fields", () => {
135
+ const event = makeProtocolEvent("tools", {
136
+ event: "tool-started",
137
+ toolCallId: "toolu_abc",
138
+ toolName: "read_file",
139
+ input: { path: "/src/main.ts" },
140
+ }, { namespace: ["tools:toolu_abc"] });
141
+ const result = normalize(event);
142
+ expect(result).toHaveLength(1);
143
+ expect(result[0]).toMatchObject({
144
+ kind: "tool_started",
145
+ callId: "toolu_abc",
146
+ name: "read_file",
147
+ });
148
+ });
149
+
150
+ it("normalizes tool-finished to the row's result string", () => {
151
+ const result = normalize(makeToolFinished("toolu_abc", "file content here"));
152
+ expect(result).toHaveLength(1);
153
+ expect(result[0]).toMatchObject({
154
+ kind: "tool_finished",
155
+ callId: "toolu_abc",
156
+ result: "file content here",
157
+ });
158
+ });
159
+
160
+ it("normalizes tool-error", () => {
161
+ const result = normalize(makeToolError("toolu_abc", "permission denied"));
162
+ expect(result).toHaveLength(1);
163
+ expect(result[0]).toMatchObject({
164
+ kind: "tool_error",
165
+ callId: "toolu_abc",
166
+ message: "permission denied",
167
+ });
168
+ });
169
+
170
+ it("normalizes tool-output-delta", () => {
171
+ const result = normalize(makeToolOutputDelta("toolu_abc", "partial output"));
172
+ expect(result).toHaveLength(1);
173
+ expect(result[0]).toMatchObject({
174
+ kind: "tool_output_delta",
175
+ callId: "toolu_abc",
176
+ delta: "partial output",
177
+ });
178
+ });
179
+
180
+ it("parses string JSON input into object", () => {
181
+ const result = normalize(makeToolStarted("toolu_abc", "think", '{"thought":"test"}'));
182
+ expect(result[0]).toMatchObject({
183
+ kind: "tool_started",
184
+ input: { thought: "test" },
185
+ });
186
+ });
187
+
188
+ it("handles malformed JSON input gracefully", () => {
189
+ const result = normalize(makeToolStarted("toolu_abc", "think", "not json"));
190
+ expect(result[0]).toMatchObject({
191
+ kind: "tool_started",
192
+ input: {},
193
+ });
194
+ });
195
+ });
196
+
197
+ // ── The tool result: the engine's envelope, rendered here ──
198
+
199
+ describe("tool-finished output → result string", () => {
200
+ // Image/mixed content blocks (e.g. a computer-use screenshot). The result
201
+ // must be the BLOCKS ARRAY serialized — not the LangChain envelope around
202
+ // it — so the persist-time offload can detect the image and lift it into
203
+ // a renderable ToolCallOutputRef.
204
+ const imageBlock = { type: "image_url", image_url: { url: "data:image/png;base64,AAAA" } };
205
+ const resultOf = (output: unknown): string => {
206
+ const [event] = normalize(makeToolFinished("toolu_x", output));
207
+ if (event?.kind !== "tool_finished") throw new Error("expected one tool_finished");
208
+ return event.result;
209
+ };
210
+ const envelope = (content: unknown) => ({
211
+ lc: 1,
212
+ type: "constructor",
213
+ id: ["langchain_core", "messages", "ToolMessage"],
214
+ kwargs: { status: "success", content },
215
+ });
216
+
217
+ it("passes a plain string output through unchanged", () => {
218
+ expect(resultOf("just text")).toBe("just text");
219
+ });
220
+
221
+ it("unwraps a ToolMessage envelope to its text content", () => {
222
+ expect(resultOf(envelope("hello"))).toBe("hello");
223
+ });
224
+
225
+ it("serializes the blocks array (not the envelope) when the content is an array", () => {
226
+ const result = resultOf(envelope([{ type: "text", text: "shot" }, imageBlock]));
227
+ expect(JSON.parse(result)).toEqual([{ type: "text", text: "shot" }, imageBlock]);
228
+ expect(result).not.toContain("constructor");
229
+ expect(result).not.toContain("langchain_core");
230
+ });
231
+
232
+ it("serializes the blocks array on a live ToolMessage-shaped object (obj.content)", () => {
233
+ expect(JSON.parse(resultOf({ content: [imageBlock] }))).toEqual([imageBlock]);
234
+ });
235
+
236
+ it("falls back to JSON.stringify for unrecognized shapes", () => {
237
+ expect(resultOf({ foo: "bar" })).toBe(JSON.stringify({ foo: "bar" }));
238
+ });
239
+
240
+ // Since #1097: a state-mutating tool (deepagents' write_todos,
241
+ // task) returns a LangGraph Command with its ToolMessage nested in the
242
+ // update; the row shows that message's content, never the whole Command.
243
+ it("unwraps a LangGraph Command to its ToolMessage's content", () => {
244
+ const command = {
245
+ lg_name: "Command",
246
+ update: {
247
+ todos: [{ content: "Read the fixture", status: "pending" }],
248
+ messages: [envelope("Updated todo list to [...]")],
249
+ },
250
+ goto: [],
251
+ };
252
+ expect(resultOf(command)).toBe("Updated todo list to [...]");
253
+ });
254
+
255
+ it("unwraps a Command whose ToolMessage carries a blocks array to the array (the task tool's shape)", () => {
256
+ const command = { lg_name: "Command", update: { files: {}, messages: [envelope([{ type: "text", text: "forty-two" }])] }, goto: [] };
257
+ expect(JSON.parse(resultOf(command))).toEqual([{ type: "text", text: "forty-two" }]);
258
+ });
259
+
260
+ it("reads the LAST message of a Command that carries several, and serializes a Command with none as it came", () => {
261
+ const several = { lg_name: "Command", update: { messages: [envelope("first"), envelope("the tool's reply")] } };
262
+ expect(resultOf(several)).toBe("the tool's reply");
263
+ const none = { lg_name: "Command", update: { todos: [] }, goto: [] };
264
+ expect(resultOf(none)).toBe(JSON.stringify(none));
265
+ });
266
+ });
267
+
268
+ // ── Usage, read beside the transcript ────────────────────────────
269
+
270
+ describe("usageOf — what the loop reads off the wire", () => {
271
+ it("reads a message-finish's usage, the cache buckets included", () => {
272
+ expect(usageOf(makeMessageFinish("run-1", {
273
+ usage: { input_tokens: 100, output_tokens: 20, total_tokens: 120, input_token_details: { cache_creation: 40, cache_read: 5 } },
274
+ }))).toEqual({
275
+ input_tokens: 100,
276
+ output_tokens: 20,
277
+ total_tokens: 120,
278
+ input_token_details: { cache_creation: 40, cache_read: 5 },
279
+ });
280
+ });
281
+
282
+ it("is undefined for a message-finish without usage", () => {
283
+ expect(usageOf(makeMessageFinish("run-1"))).toBeUndefined();
284
+ });
285
+
286
+ it("ignores the standalone usage event — v3 emits both for one turn, and reading both would double-count", () => {
287
+ expect(usageOf(makeUsageEvent("run-1", { input_tokens: 50, output_tokens: 10 }))).toBeUndefined();
288
+ });
289
+
290
+ it("reads a sub-agent's finish too — its spend is the execution's", () => {
291
+ expect(usageOf(makeMessageFinish("sub-run", {
292
+ namespace: ["tools:task-1", "model_request:sub-run"],
293
+ usage: { input_tokens: 600, output_tokens: 12 },
294
+ }))).toMatchObject({ input_tokens: 600, output_tokens: 12 });
295
+ });
296
+
297
+ it("is undefined for every other channel", () => {
298
+ expect(usageOf(makeTextDelta("run-1", "hi"))).toBeUndefined();
299
+ expect(usageOf(makeToolFinished("toolu_abc", "ok"))).toBeUndefined();
300
+ expect(usageOf(makeLifecycleCompleted("root"))).toBeUndefined();
301
+ });
302
+ });
303
+
304
+ // ── Lifecycle channel: carried by the wire, not the transcript ───
305
+
306
+ describe("lifecycle channel", () => {
307
+ it("emits nothing for running", () => {
308
+ expect(normalize(makeLifecycleRunning("root"))).toHaveLength(0);
309
+ });
310
+
311
+ it("emits nothing for completed", () => {
312
+ expect(normalize(makeLifecycleCompleted("model_request", ["model_request:abc"]))).toHaveLength(0);
313
+ });
314
+ });
315
+
316
+ // ── Ignored channels ─────────────────────────────────────────────
317
+
318
+ describe("ignored channels", () => {
319
+ it("returns empty for checkpoints", () => {
320
+ expect(normalize(makeCheckpointEvent())).toHaveLength(0);
321
+ });
322
+
323
+ it("returns empty for tasks", () => {
324
+ expect(normalize(makeTasksEvent())).toHaveLength(0);
325
+ });
326
+
327
+ it("returns empty for values", () => {
328
+ expect(normalize(makeValuesEvent())).toHaveLength(0);
329
+ });
330
+
331
+ it("returns empty for updates", () => {
332
+ expect(normalize(makeUpdatesEvent())).toHaveLength(0);
333
+ });
334
+ });
335
+
336
+ // ── Edge cases ───────────────────────────────────────────────────
337
+
338
+ describe("edge cases", () => {
339
+ it("returns empty for unknown method", () => {
340
+ const event = makeProtocolEvent("input", { event: "something" });
341
+ expect(normalize(event)).toHaveLength(0);
342
+ });
343
+
344
+ it("returns empty for missing data", () => {
345
+ const event = makeProtocolEvent("messages", undefined);
346
+ expect(normalize(event)).toHaveLength(0);
347
+ });
348
+
349
+ it("returns empty for unknown message event type", () => {
350
+ const event = makeProtocolEvent("messages", { event: "brand-new-thing", run_id: "r" });
351
+ expect(normalize(event)).toHaveLength(0);
352
+ });
353
+
354
+ it("carries no namespace and no scope — the core is root-scoped; scope is the translator's", () => {
355
+ const result = normalize(makeTextDelta("run-1", "hi", { namespace: ["tools:x", "model_request:y"] }));
356
+ expect(result[0]).not.toHaveProperty("namespace");
357
+ expect(result[0]).not.toHaveProperty("subAgentId");
358
+ });
359
+
360
+ it("carries neither seq nor node — the recorder keeps them on the raw event; no handler reads them", () => {
361
+ const event = makeTextDelta("run-1", "hi");
362
+ const result = normalize(event);
363
+ expect(result[0]).not.toHaveProperty("seq");
364
+ expect(result[0]).not.toHaveProperty("node");
365
+ });
366
+
367
+ it("handles delta with no type gracefully", () => {
368
+ const event = makeProtocolEvent("messages", {
369
+ event: "content-block-delta",
370
+ index: 0,
371
+ delta: {},
372
+ run_id: "run-1",
373
+ });
374
+ expect(normalize(event)).toHaveLength(0);
375
+ });
376
+
377
+ it("handles missing tool_call_id in tool-started", () => {
378
+ const event = makeProtocolEvent("tools", {
379
+ event: "tool-started",
380
+ tool_name: "read_file",
381
+ }, { namespace: ["tools:abc"] });
382
+ const result = normalize(event);
383
+ expect(result).toHaveLength(1);
384
+ expect(result[0]).toMatchObject({ kind: "tool_started", callId: "" });
385
+ });
386
+ });
387
+
388
+ // ── Scope and the sub-agent lifecycle: the translator over the core ──
389
+
390
+ describe("DeepAgentTranslator — scope by LangGraph namespace, a sub-agent per task call", () => {
391
+ const TASK_NS = ["tools:pregel-1"];
392
+ const CHILD_NS = ["tools:pregel-1", "model_request:inner-1"];
393
+ const CHILD_TOOL_NS = ["tools:pregel-1", "tools:inner-tool"];
394
+
395
+ function translator(): DeepAgentTranslator {
396
+ return new DeepAgentTranslator(null);
397
+ }
398
+
399
+ it("a root event carries no subAgentId", () => {
400
+ const [event] = translator().translate(makeTextDelta("run-1", "hi"));
401
+ expect(event).toEqual({ kind: "text_delta", runId: "run-1", text: "hi" });
402
+ });
403
+
404
+ it("a task start at depth 1 opens a sub-agent BEFORE its own row, keyed by the call id, named from its args", () => {
405
+ const events = translator().translate(
406
+ makeToolStarted("task-1", "task", { subagent_type: "helper", description: "Look it up." }, { namespace: TASK_NS }),
407
+ );
408
+ expect(events.map((e) => e.kind)).toEqual(["sub_agent_started", "tool_started"]);
409
+ expect(events[0]).toEqual({
410
+ kind: "sub_agent_started",
411
+ subAgentId: "task-1",
412
+ name: "helper",
413
+ subject: "Look it up.",
414
+ input: "Look it up.",
415
+ });
416
+ expect(events[1]).toMatchObject({ kind: "tool_started", callId: "task-1", name: "task" });
417
+ expect(events[1]).not.toHaveProperty("subAgentId");
418
+ });
419
+
420
+ it("a task start with no subagent_type is named after the tool", () => {
421
+ const [opened] = translator().translate(makeToolStarted("task-2", "task", {}, { namespace: TASK_NS }));
422
+ expect(opened).toMatchObject({ kind: "sub_agent_started", name: "task", subject: "", input: "" });
423
+ });
424
+
425
+ it("events under a registered prefix, two or more segments deep, are the sub-agent's", () => {
426
+ const t = translator();
427
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
428
+ const [text] = t.translate(makeTextDelta("inner-1", "Working.", { namespace: CHILD_NS }));
429
+ expect(text).toEqual({ kind: "text_delta", runId: "inner-1", text: "Working.", subAgentId: "task-1" });
430
+ const [tool] = t.translate(makeToolStarted("inner-tool", "grep", { pattern: "x" }, { namespace: CHILD_TOOL_NS }));
431
+ expect(tool).toMatchObject({ kind: "tool_started", callId: "inner-tool", subAgentId: "task-1", mcpServerSlug: "" });
432
+ });
433
+
434
+ it("a task start INSIDE a sub-agent is an ordinary row of that sub-agent — one level of delegation is tracked", () => {
435
+ const t = translator();
436
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
437
+ const events = t.translate(makeToolStarted("nested", "task", { subagent_type: "deeper" }, { namespace: CHILD_TOOL_NS }));
438
+ expect(events.map((e) => e.kind)).toEqual(["tool_started"]);
439
+ expect(events[0]).toMatchObject({ subAgentId: "task-1" });
440
+ });
441
+
442
+ it("a nested namespace whose prefix nobody registered folds into the root", () => {
443
+ const [event] = translator().translate(makeTextDelta("r", "hi", { namespace: ["tools:unknown", "model_request:x"] }));
444
+ expect(event).not.toHaveProperty("subAgentId");
445
+ });
446
+
447
+ it("a one-segment event under a registered prefix is the ROOT's — the task row's own lifecycle", () => {
448
+ const t = translator();
449
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
450
+ const [finished] = t.translate(makeToolOutputDelta("task-1", "…", { namespace: TASK_NS }));
451
+ expect(finished).not.toHaveProperty("subAgentId");
452
+ });
453
+
454
+ it("the task's finish closes the sub-agent AFTER the row's own finish, with the same result as its output", () => {
455
+ const t = translator();
456
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
457
+ const events = t.translate(makeToolFinished("task-1", "forty-two", { namespace: TASK_NS }));
458
+ expect(events).toEqual([
459
+ { kind: "tool_finished", callId: "task-1", result: "forty-two" },
460
+ { kind: "sub_agent_finished", subAgentId: "task-1", output: "forty-two" },
461
+ ]);
462
+ });
463
+
464
+ it("the task's error fails the sub-agent after the row's own error", () => {
465
+ const t = translator();
466
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
467
+ const events = t.translate(makeToolError("task-1", "boom", { namespace: TASK_NS }));
468
+ expect(events).toEqual([
469
+ { kind: "tool_error", callId: "task-1", message: "boom" },
470
+ { kind: "sub_agent_failed", subAgentId: "task-1", error: "boom" },
471
+ ]);
472
+ });
473
+
474
+ it("an ordinary tool's finish closes no sub-agent", () => {
475
+ const t = translator();
476
+ const events = t.translate(makeToolFinished("toolu_1", "ok"));
477
+ expect(events.map((e) => e.kind)).toEqual(["tool_finished"]);
478
+ });
479
+
480
+ it("a depth-0 task start (no namespace) still opens a sub-agent, under a synthetic prefix its children can name", () => {
481
+ const t = translator();
482
+ const events = t.translate(makeToolStarted("task-0", "task", { subagent_type: "w" }, { namespace: [] }));
483
+ expect(events[0]).toMatchObject({ kind: "sub_agent_started", subAgentId: "task-0" });
484
+ const [child] = t.translate(makeTextDelta("in", "hi", { namespace: ["tools:task-0", "model_request:in"] }));
485
+ expect(child).toMatchObject({ subAgentId: "task-0" });
486
+ });
487
+
488
+ it("attributes root calls only: a sub-agent's tool start carries no server and no provenance even under a gate", () => {
489
+ const t = new DeepAgentTranslator({
490
+ policies: new Map(),
491
+ toolServerMap: new Map([["grep", "search-server"]]),
492
+ leasedCategories: new Set(),
493
+ globalBypass: false,
494
+ unattended: false,
495
+ unattendedSkips: new Set(),
496
+ });
497
+ t.translate(makeToolStarted("task-1", "task", { subagent_type: "helper" }, { namespace: TASK_NS }));
498
+ const [root] = t.translate(makeToolStarted("root-grep", "grep", {}));
499
+ expect(root).toMatchObject({ mcpServerSlug: "search-server", provenance: "classifier_default" });
500
+ const [sub] = t.translate(makeToolStarted("sub-grep", "grep", {}, { namespace: CHILD_TOOL_NS }));
501
+ expect(sub).toMatchObject({ subAgentId: "task-1", mcpServerSlug: "" });
502
+ expect(sub).not.toHaveProperty("provenance");
503
+ });
504
+ });
505
+ });
@@ -6,21 +6,25 @@
6
6
  *
7
7
  * - how the graph is invoked (the two-arg v3 `streamEvents` shape, the
8
8
  * runtime's `langgraphConfig` carried whole, the loop's own abort signal);
9
- * - what each event becomes (the normalizer feeds the builder; the sink
9
+ * - what each event becomes (the translator feeds the builder; the sink
10
10
  * learns of activity per event, with the tool's name as the detail);
11
11
  * - what the sink is told and when (usage priced per `message_finish`;
12
12
  * a persist requested on the shared cadence rule, a tool start forcing it);
13
- * - how the loop ends: `completed` with the run's output, `awaiting_approval`
14
- * at a gate, `interrupted` when the runtime stops it — taken at the NEXT
15
- * event, the engine's own step boundary (S3 M2a F-M2a-18), and before the
16
- * first if the stop came earlier;
13
+ * - how the loop ends: `completed` with the run's output, `interrupted` when
14
+ * the runtime stops it — taken at the NEXT event, the engine's own step
15
+ * boundary, and before the first if the stop came
16
+ * earlier. (`awaiting_approval` from the stream itself has no producer
17
+ * on native since #1097: a held call never emits a
18
+ * `tool_started`, so the builder never leaves a row WAITING during the
19
+ * stream; the gate's hold reaches the transcript at the settle. The arm
20
+ * that pinned that path went with it.)
17
21
  * - what it refuses and what it tolerates: an empty stream throws; the
18
22
  * engine's own error propagates; a `run.output` that rejects is logged
19
23
  * and the turn completes without a final state;
20
24
  * - the recorder exists only under `V3_EVENT_RECORD_DIR`.
21
25
  *
22
26
  * Carried from the legacy v3 loop's suite (`streaming-v3.test.ts`, retired
23
- * with the loop at S3 M2b, Q-M2b-5): the arms whose rule the adapter's loop
27
+ * with the loop in #1096): the arms whose rule the adapter's loop
24
28
  * still has, re-stated against the sink. The loop-specific arms it dropped
25
29
  * (the in-band heartbeat timer, the 120 s stall, STOP read from the persist,
26
30
  * pause as a terminal status) are the turn runtime's now and pinned in
@@ -39,7 +43,6 @@ import { makeInMemoryArtifactStorage } from "../../../__test-utils__/fake-artifa
39
43
  import { turnInputFixture } from "../../../__test-utils__/turn-input-fixture.js";
40
44
  import type { WorkspaceBackend } from "../../../shared/workspace/types.js";
41
45
  import type { ModelPricing } from "../../../shared/model-pricing.js";
42
- import type { MergedToolPolicy } from "../../../shared/approval-policy.js";
43
46
  import { CasCaptureObserver } from "../cas-capture-observer.js";
44
47
  import type { DeepAgentEngine, DeepAgentGateState, DeepAgentGraphInput, DeepAgentWorkspace } from "../turn-setup.js";
45
48
  import { consumeDeepAgentStream, createDeepAgentTranscript, type StreamableRun } from "../turn-stream.js";
@@ -185,7 +188,7 @@ describe("consumeDeepAgentStream — how the graph is invoked", () => {
185
188
  });
186
189
 
187
190
  describe("consumeDeepAgentStream — what each event becomes", () => {
188
- it("feeds every event through the normalizer into the transcript and completes with the run's output", async () => {
191
+ it("feeds every event through the translator into the transcript and completes with the run's output", async () => {
189
192
  const h = harness();
190
193
  const result = await h.run(
191
194
  scriptedRun(
@@ -258,27 +261,6 @@ describe("consumeDeepAgentStream — what each event becomes", () => {
258
261
  });
259
262
 
260
263
  describe("consumeDeepAgentStream — how the loop ends", () => {
261
- it("ends awaiting_approval when the builder leaves a gated tool WAITING, without awaiting the run's output", async () => {
262
- const policy: MergedToolPolicy = {
263
- toolName: "dangerous_tool",
264
- mcpServerSlug: "my-server",
265
- requiresApproval: true,
266
- approvalMessage: "Approve?",
267
- source: "classifier_default",
268
- };
269
- const h = harness({
270
- gate: openGate({ policies: new Map([["my-server/dangerous_tool", policy]]), toolServerMap: new Map([["dangerous_tool", "my-server"]]) }),
271
- });
272
- const neverResolves = new Promise<unknown>(() => undefined);
273
- const result = await h.run(
274
- scriptedRun([...textTurn("run-1", "Gated."), makeToolStarted("toolu_g", "dangerous_tool", { target: "prod" })], { output: () => neverResolves }),
275
- );
276
-
277
- expect(result.reason).toBe("awaiting_approval");
278
- expect(result.runOutput).toBeUndefined();
279
- expect(h.sink.status.messages[0].toolCalls[0].status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
280
- });
281
-
282
264
  it("a stop before the first event settles interrupted without invoking the graph", async () => {
283
265
  const h = harness();
284
266
  h.sink.abort("stopped before start");
@@ -30,7 +30,7 @@
30
30
  * (the thread id is the runtime's, `deterministic`), or import
31
31
  * `@temporalio/*` (`__tests__/adapter-is-temporal-free.test.ts`).
32
32
  *
33
- * Extracted from `index.ts` `createDeepAgentActivities` at S3 M2a on the
33
+ * Extracted from `index.ts` `createDeepAgentActivities` in #1096 on the
34
34
  * Cursor adapter's layout (`execute-cursor/adapter.ts`).
35
35
  */
36
36
 
@@ -1,35 +1,34 @@
1
1
  /**
2
2
  * Pre-execution args capture for the HITL approval gate (native harness).
3
3
  *
4
- * When the graph pauses for approval — before the tool runs — this captures a
5
- * sanitized args preview so the gate can show the proposed change. It owns only
6
- * the native-specific seam: correlating a gated `tool_call_id` to its arguments
7
- * from graph state (the authoritative single source of truth at the interrupt,
8
- * since the streamed input cache is empty and the interrupt value carries only a
9
- * few fields). The approval card renders the proposed write/edit content from
10
- * these args; there is no separate captured `file_changes` (removed in Phase 5
11
- * Slice 4 — the args are the single source, and the Cursor deny-gate's
12
- * exact-apply reads the same args on resume; see shared/exact-apply.ts).
4
+ * When the graph pauses for approval — before the tool runs — this recovers
5
+ * the proposed call's arguments so the gate can show the proposed change. It
6
+ * owns only the native-specific seam: correlating a gated `tool_call_id` to
7
+ * its arguments from graph state (the authoritative single source of truth at
8
+ * the interrupt, since the streamed input cache is empty and the interrupt
9
+ * value carries only a few fields). The approval card renders the proposed
10
+ * write/edit content from these args; there is no separate captured
11
+ * `file_changes` (removed in Phase 5 Slice 4 — the args are the single
12
+ * source, and the Cursor deny-gate's exact-apply reads the same args on
13
+ * resume; see shared/exact-apply.ts). The row's `args_preview` is the
14
+ * builder's to write from these args (since #1097; until then this module
15
+ * rendered it too, a second call of the one sanitizer).
13
16
  *
14
17
  * @since First-Class Diff Review (#186), approval-gate phase
15
18
  */
16
19
 
17
20
  /** What the gate capture contributes to a `WAITING_APPROVAL` `ToolCall`. */
18
21
  export interface ApprovalCaptureResult {
19
- /** Sanitized JSON args preview, omitted when there are no args to show. */
20
- readonly argsPreview?: string;
21
22
  /**
22
23
  * The secret-redacted args object, for stamping `ToolCall.args` on the
23
- * interrupt-placeholder row. Without it the placeholder carried ONLY the
24
- * preview string, so every args-driven UI read — the row header's
25
- * filename-first path above all — rendered nothing for a pending gate
26
- * (issue #754). Redacted (never raw): the placeholder must not widen the
27
- * exposure the preview sanitizer bounds.
24
+ * proposed row. Without it the row carried ONLY the preview string, so
25
+ * every args-driven UI read — the row header's filename-first path above
26
+ * all — rendered nothing for a pending gate (issue #754). Redacted (never
27
+ * raw): the row must not widen the exposure the preview sanitizer bounds.
28
28
  */
29
29
  readonly args?: Record<string, unknown>;
30
30
  }
31
31
 
32
- import { sanitizeArgsPreview } from "./status-builder-shared.js";
33
32
  import { redactSensitiveArgs } from "../../shared/args-preview.js";
34
33
 
35
34
  /**
@@ -72,11 +71,11 @@ export function findAiMessageToolCallArgs(
72
71
  }
73
72
 
74
73
  /**
75
- * Capture the gate's args preview from a single correlation lookup, keeping the
76
- * call site thin.
74
+ * Capture the gate's redacted args from a single correlation lookup, keeping
75
+ * the call site thin.
77
76
  *
78
77
  * Returns an empty result when the tool call cannot be correlated or took no
79
- * arguments, so the gate falls back to today's behavior for that interrupt.
78
+ * arguments, so the proposed row carries no args for that interrupt.
80
79
  */
81
80
  export function captureApprovalArtifacts(opts: {
82
81
  readonly toolCallId: string;
@@ -85,6 +84,5 @@ export function captureApprovalArtifacts(opts: {
85
84
  const args = findAiMessageToolCallArgs(opts.messages, opts.toolCallId);
86
85
  if (!args || Object.keys(args).length === 0) return {};
87
86
 
88
- const argsPreview = sanitizeArgsPreview(args) || undefined;
89
- return { argsPreview, args: redactSensitiveArgs(args) };
87
+ return { args: redactSensitiveArgs(args) };
90
88
  }