@stigmer/runner 3.15.3-dev.20260914121148 → 3.16.0

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 (592) hide show
  1. package/README.md +2 -1
  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 +2 -2
  12. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
  13. package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
  14. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
  15. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
  16. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  17. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +47 -12
  18. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +41 -10
  19. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  20. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +15 -6
  21. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +17 -4
  22. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
  23. package/dist/activities/execute-cursor/adapter.d.ts +4 -4
  24. package/dist/activities/execute-cursor/adapter.js +4 -4
  25. package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
  26. package/dist/activities/execute-cursor/approval-policy.js +12 -23
  27. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  28. package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
  29. package/dist/activities/execute-cursor/approval-state.js +65 -0
  30. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  31. package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
  32. package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
  33. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
  34. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
  35. package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
  36. package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
  37. package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
  38. package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
  39. package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
  40. package/dist/activities/execute-cursor/prompt-builder.js +4 -4
  41. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  42. package/dist/activities/execute-cursor/service-tier.js +1 -2
  43. package/dist/activities/execute-cursor/service-tier.js.map +1 -1
  44. package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
  45. package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
  46. package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
  47. package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
  48. package/dist/activities/execute-cursor/tool-result.js +130 -0
  49. package/dist/activities/execute-cursor/tool-result.js.map +1 -0
  50. package/dist/activities/execute-cursor/translator.d.ts +178 -0
  51. package/dist/activities/execute-cursor/translator.js +485 -0
  52. package/dist/activities/execute-cursor/translator.js.map +1 -0
  53. package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
  54. package/dist/activities/execute-cursor/turn-boundary.js +10 -14
  55. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  56. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  57. package/dist/activities/execute-cursor/turn-settle.js +47 -34
  58. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  59. package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
  60. package/dist/activities/execute-cursor/turn-setup.js +5 -5
  61. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  62. package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
  63. package/dist/activities/execute-cursor/turn-stream.js +41 -28
  64. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  65. package/dist/activities/execute-cursor/turn.d.ts +4 -4
  66. package/dist/activities/execute-cursor/turn.js +5 -5
  67. package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
  68. package/dist/activities/execute-cursor/usage-pricing.js +2 -2
  69. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
  70. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
  71. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
  72. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
  73. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  74. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
  75. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
  76. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
  77. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
  78. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
  79. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
  80. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
  81. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  82. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
  83. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
  84. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
  85. package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
  86. package/dist/activities/execute-deep-agent/adapter.js +1 -1
  87. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
  88. package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
  89. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
  91. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
  92. package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
  93. package/dist/activities/execute-deep-agent/hitl.js +2 -2
  94. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
  95. package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
  96. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  97. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
  98. package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
  99. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  100. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
  101. package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
  102. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  103. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
  104. package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
  105. package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
  106. package/dist/activities/execute-deep-agent/translator.js +418 -0
  107. package/dist/activities/execute-deep-agent/translator.js.map +1 -0
  108. package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
  109. package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
  110. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
  112. package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
  113. package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
  114. package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
  115. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  116. package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
  117. package/dist/activities/execute-deep-agent/turn.js +3 -3
  118. package/dist/activities/generate-session-subject.d.ts +25 -4
  119. package/dist/activities/generate-session-subject.js +17 -7
  120. package/dist/activities/generate-session-subject.js.map +1 -1
  121. package/dist/client/stigmer-client.d.ts +17 -6
  122. package/dist/client/stigmer-client.js +47 -14
  123. package/dist/client/stigmer-client.js.map +1 -1
  124. package/dist/config.d.ts +6 -3
  125. package/dist/config.js +4 -1
  126. package/dist/config.js.map +1 -1
  127. package/dist/harness/approval-decisions.d.ts +1 -1
  128. package/dist/harness/approval-decisions.js +1 -1
  129. package/dist/harness/capabilities.d.ts +21 -11
  130. package/dist/harness/capabilities.js +2 -2
  131. package/dist/harness/capture.d.ts +4 -4
  132. package/dist/harness/capture.js +4 -4
  133. package/dist/harness/persist-chokepoint.d.ts +3 -3
  134. package/dist/harness/persist-chokepoint.js +3 -3
  135. package/dist/harness/registry.d.ts +2 -2
  136. package/dist/harness/registry.js +2 -2
  137. package/dist/harness/run-turn.d.ts +6 -4
  138. package/dist/harness/run-turn.js +31 -9
  139. package/dist/harness/run-turn.js.map +1 -1
  140. package/dist/harness/stop-controller.d.ts +1 -1
  141. package/dist/harness/stop-controller.js +1 -1
  142. package/dist/harness/terminal-table.d.ts +7 -7
  143. package/dist/harness/terminal-table.js +7 -7
  144. package/dist/harness/transcript/builder.d.ts +182 -0
  145. package/dist/harness/transcript/builder.js +693 -0
  146. package/dist/harness/transcript/builder.js.map +1 -0
  147. package/dist/harness/transcript/events.d.ts +218 -0
  148. package/dist/harness/transcript/events.js +50 -0
  149. package/dist/harness/transcript/events.js.map +1 -0
  150. package/dist/harness/transcript/state.d.ts +110 -0
  151. package/dist/harness/transcript/state.js +148 -0
  152. package/dist/harness/transcript/state.js.map +1 -0
  153. package/dist/harness/turn-context.d.ts +54 -38
  154. package/dist/harness/turn-context.js +42 -43
  155. package/dist/harness/turn-context.js.map +1 -1
  156. package/dist/harness/types.d.ts +63 -22
  157. package/dist/harness/types.js +12 -11
  158. package/dist/harness/types.js.map +1 -1
  159. package/dist/harness/usage-accumulator.d.ts +2 -2
  160. package/dist/harness/usage-accumulator.js +2 -2
  161. package/dist/harness-adapters.d.ts +5 -4
  162. package/dist/harness-adapters.js +5 -4
  163. package/dist/harness-adapters.js.map +1 -1
  164. package/dist/interceptors/run-credential-activity.d.ts +28 -0
  165. package/dist/interceptors/run-credential-activity.js +56 -0
  166. package/dist/interceptors/run-credential-activity.js.map +1 -0
  167. package/dist/middleware/approval-gate.d.ts +6 -0
  168. package/dist/middleware/approval-gate.js +7 -57
  169. package/dist/middleware/approval-gate.js.map +1 -1
  170. package/dist/middleware/cost-advisory.d.ts +3 -3
  171. package/dist/middleware/cost-advisory.js +3 -3
  172. package/dist/middleware/index.d.ts +1 -1
  173. package/dist/middleware/index.js +1 -1
  174. package/dist/runner-manager.js +10 -4
  175. package/dist/runner-manager.js.map +1 -1
  176. package/dist/shared/activity-input.d.ts +9 -0
  177. package/dist/shared/activity-input.js +17 -0
  178. package/dist/shared/activity-input.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-zip.d.ts +2 -2
  188. package/dist/shared/attachment-zip.js +2 -2
  189. package/dist/shared/channel-attachment.d.ts +8 -5
  190. package/dist/shared/channel-attachment.js +10 -6
  191. package/dist/shared/channel-attachment.js.map +1 -1
  192. package/dist/shared/cost-guard.d.ts +2 -2
  193. package/dist/shared/cost-guard.js +2 -2
  194. package/dist/shared/exact-apply.d.ts +1 -1
  195. package/dist/shared/exact-apply.js +1 -1
  196. package/dist/shared/execution-context.d.ts +2 -2
  197. package/dist/shared/execution-context.js +2 -2
  198. package/dist/shared/extract-structured-output.d.ts +2 -2
  199. package/dist/shared/extract-structured-output.js +2 -2
  200. package/dist/shared/filereview/cas-touched.d.ts +2 -2
  201. package/dist/shared/filereview/cas-touched.js +2 -2
  202. package/dist/shared/filereview/progress.d.ts +13 -0
  203. package/dist/shared/filereview/progress.js +13 -0
  204. package/dist/shared/filereview/progress.js.map +1 -1
  205. package/dist/shared/heartbeat.d.ts +1 -1
  206. package/dist/shared/heartbeat.js +1 -1
  207. package/dist/shared/llm-backend.d.ts +0 -4
  208. package/dist/shared/llm-backend.js +0 -4
  209. package/dist/shared/llm-backend.js.map +1 -1
  210. package/dist/shared/memory-attachment.d.ts +16 -9
  211. package/dist/shared/memory-attachment.js +18 -10
  212. package/dist/shared/memory-attachment.js.map +1 -1
  213. package/dist/shared/model-error.d.ts +1 -2
  214. package/dist/shared/model-error.js +1 -2
  215. package/dist/shared/model-error.js.map +1 -1
  216. package/dist/shared/persist-decision.d.ts +18 -24
  217. package/dist/shared/persist-decision.js +19 -11
  218. package/dist/shared/persist-decision.js.map +1 -1
  219. package/dist/shared/prompt-sections.d.ts +4 -4
  220. package/dist/shared/prompt-sections.js +4 -4
  221. package/dist/shared/run-credential-store.d.ts +32 -0
  222. package/dist/shared/run-credential-store.js +39 -0
  223. package/dist/shared/run-credential-store.js.map +1 -0
  224. package/dist/shared/run-credential.d.ts +61 -0
  225. package/dist/shared/run-credential.js +68 -0
  226. package/dist/shared/run-credential.js.map +1 -0
  227. package/dist/shared/skill-resolver.d.ts +3 -3
  228. package/dist/shared/skill-resolver.js +3 -3
  229. package/dist/shared/status-offload.d.ts +1 -1
  230. package/dist/shared/status-offload.js +2 -2
  231. package/dist/shared/status-offload.js.map +1 -1
  232. package/dist/shared/streaming-scheduler.d.ts +2 -7
  233. package/dist/shared/streaming-scheduler.js +6 -14
  234. package/dist/shared/streaming-scheduler.js.map +1 -1
  235. package/dist/shared/subagent-rows.d.ts +2 -2
  236. package/dist/shared/subagent-rows.js +2 -2
  237. package/dist/shared/synthesized-attachment.d.ts +30 -3
  238. package/dist/shared/synthesized-attachment.js +26 -0
  239. package/dist/shared/synthesized-attachment.js.map +1 -1
  240. package/dist/shared/todos.d.ts +3 -3
  241. package/dist/shared/todos.js +3 -3
  242. package/dist/shared/tool-row.d.ts +19 -1
  243. package/dist/shared/tool-row.js +36 -2
  244. package/dist/shared/tool-row.js.map +1 -1
  245. package/dist/shared/worker-shutdown.d.ts +1 -1
  246. package/dist/shared/worker-shutdown.js +1 -1
  247. package/dist/shared/workspace/session-provision.d.ts +1 -1
  248. package/dist/shared/workspace/session-provision.js +1 -1
  249. package/dist/shared/workspace/sources/empty.d.ts +1 -1
  250. package/dist/shared/workspace/sources/empty.js +1 -2
  251. package/dist/shared/workspace/sources/empty.js.map +1 -1
  252. package/dist/shared/workspace/sources/git.js +4 -4
  253. package/dist/shared/workspace/sources/git.js.map +1 -1
  254. package/dist/shared/workspace/sources/local-path.js +6 -6
  255. package/dist/shared/workspace/sources/local-path.js.map +1 -1
  256. package/dist/shared/workspace/stigmer-link.d.ts +1 -1
  257. package/dist/shared/workspace/stigmer-link.js +1 -1
  258. package/dist/shared/workspace/types.d.ts +2 -5
  259. package/dist/shared/workspace/types.js +0 -6
  260. package/dist/shared/workspace/types.js.map +1 -1
  261. package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
  262. package/dist/shared/workspace/writeback-coordinator.js +7 -9
  263. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  264. package/dist/worker.js +10 -3
  265. package/dist/worker.js.map +1 -1
  266. package/dist/workflow-source.d.ts +10 -0
  267. package/dist/workflow-source.js +12 -0
  268. package/dist/workflow-source.js.map +1 -1
  269. package/dist/workflows/execute-from-execution.d.ts +15 -0
  270. package/dist/workflows/execute-from-execution.js +11 -0
  271. package/dist/workflows/execute-from-execution.js.map +1 -1
  272. package/dist/workflows/index.d.ts +5 -3
  273. package/dist/workflows/index.js +5 -3
  274. package/dist/workflows/index.js.map +1 -1
  275. package/dist/workflows/interceptors/run-credential.d.ts +34 -0
  276. package/dist/workflows/interceptors/run-credential.js +71 -0
  277. package/dist/workflows/interceptors/run-credential.js.map +1 -0
  278. package/package.json +4 -4
  279. package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
  280. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
  281. package/src/__test-utils__/approval-contract/contract.ts +1 -1
  282. package/src/__test-utils__/approval-contract/types.ts +1 -1
  283. package/src/__test-utils__/harness-boot-order-child.ts +1 -1
  284. package/src/__test-utils__/harness-contract/contract.ts +8 -8
  285. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  286. package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
  287. package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
  288. package/src/__test-utils__/hermetic-activity.ts +113 -9
  289. package/src/__test-utils__/model-registry-fixture.ts +31 -7
  290. package/src/__test-utils__/module-specifiers.ts +32 -3
  291. package/src/__tests__/harness-boot-order.test.ts +1 -1
  292. package/src/__tests__/harness-contract.test.ts +1 -1
  293. package/src/__tests__/run-credential-e2e.test.ts +233 -0
  294. package/src/__tests__/run-credential-registration.test.ts +80 -0
  295. package/src/__tests__/runner-manager.test.ts +1 -1
  296. package/src/activities/__tests__/generate-session-subject-wire.test.ts +119 -0
  297. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +1 -1
  298. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +2 -2
  299. package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
  300. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
  301. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +67 -17
  302. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +19 -5
  303. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
  304. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
  305. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
  306. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
  307. package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
  308. package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +19 -8
  309. package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +10 -8
  310. package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
  311. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
  312. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
  313. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +1 -1
  314. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
  315. package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
  316. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
  317. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
  318. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
  319. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
  320. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
  321. package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
  322. package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
  323. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
  324. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
  325. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
  326. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +7 -7
  327. package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
  328. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +5 -5
  329. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +2 -1
  330. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +2 -1
  331. package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
  332. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
  333. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +8 -8
  334. package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
  335. package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
  336. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +1 -1
  337. package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
  338. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +3 -3
  339. package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
  340. package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
  341. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +13 -1
  342. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +2 -2
  343. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
  344. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
  345. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
  346. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
  347. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
  348. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
  349. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
  350. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
  351. package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
  352. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
  353. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
  354. package/src/activities/execute-cursor/adapter.ts +4 -4
  355. package/src/activities/execute-cursor/approval-policy.ts +12 -24
  356. package/src/activities/execute-cursor/approval-state.ts +66 -1
  357. package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
  358. package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
  359. package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
  360. package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
  361. package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
  362. package/src/activities/execute-cursor/prompt-builder.ts +6 -6
  363. package/src/activities/execute-cursor/service-tier.ts +1 -2
  364. package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
  365. package/src/activities/execute-cursor/tool-result.ts +128 -0
  366. package/src/activities/execute-cursor/translator.ts +541 -0
  367. package/src/activities/execute-cursor/turn-boundary.ts +21 -14
  368. package/src/activities/execute-cursor/turn-settle.ts +46 -34
  369. package/src/activities/execute-cursor/turn-setup.ts +5 -5
  370. package/src/activities/execute-cursor/turn-stream.ts +49 -46
  371. package/src/activities/execute-cursor/turn.ts +5 -5
  372. package/src/activities/execute-cursor/usage-pricing.ts +2 -2
  373. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
  374. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
  375. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
  376. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
  377. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
  378. package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
  379. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
  380. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
  381. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
  382. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
  383. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
  384. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
  385. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
  386. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
  387. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
  388. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
  389. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
  390. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
  391. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
  392. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
  393. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
  394. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
  395. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
  396. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
  397. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
  398. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
  399. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
  400. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
  401. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
  402. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
  403. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
  404. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
  405. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
  406. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
  407. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
  408. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
  409. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
  410. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
  411. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
  412. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
  413. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
  414. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
  415. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
  416. package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
  417. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
  418. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
  419. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
  420. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
  421. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
  422. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
  423. package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
  424. package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
  425. package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
  426. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
  427. package/src/activities/execute-deep-agent/adapter.ts +1 -1
  428. package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
  429. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
  430. package/src/activities/execute-deep-agent/hitl.ts +2 -2
  431. package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
  432. package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
  433. package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
  434. package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
  435. package/src/activities/execute-deep-agent/translator.ts +463 -0
  436. package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
  437. package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
  438. package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
  439. package/src/activities/execute-deep-agent/turn.ts +3 -3
  440. package/src/activities/generate-session-subject.ts +29 -4
  441. package/src/client/__tests__/stigmer-client.test.ts +92 -0
  442. package/src/client/stigmer-client.ts +48 -14
  443. package/src/config.ts +6 -3
  444. package/src/harness/README.md +335 -0
  445. package/src/harness/__tests__/approval-decisions.test.ts +2 -2
  446. package/src/harness/__tests__/capture.test.ts +3 -3
  447. package/src/harness/__tests__/import-direction.test.ts +3 -2
  448. package/src/harness/__tests__/mount-skills.test.ts +4 -1
  449. package/src/harness/__tests__/readme-index.test.ts +339 -0
  450. package/src/harness/__tests__/run-turn.test.ts +131 -6
  451. package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
  452. package/src/harness/__tests__/transcript-writers.test.ts +191 -0
  453. package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
  454. package/src/harness/__tests__/turn-context.test.ts +5 -5
  455. package/src/harness/approval-decisions.ts +1 -1
  456. package/src/harness/capabilities.ts +21 -11
  457. package/src/harness/capture.ts +4 -4
  458. package/src/harness/persist-chokepoint.ts +3 -3
  459. package/src/harness/registry.ts +2 -2
  460. package/src/harness/run-turn.ts +33 -9
  461. package/src/harness/stop-controller.ts +1 -1
  462. package/src/harness/terminal-table.ts +7 -7
  463. package/src/harness/transcript/__tests__/builder.test.ts +975 -0
  464. package/src/harness/transcript/__tests__/state.test.ts +143 -0
  465. package/src/harness/transcript/builder.ts +755 -0
  466. package/src/harness/transcript/events.ts +262 -0
  467. package/src/harness/transcript/state.ts +167 -0
  468. package/src/harness/turn-context.ts +61 -46
  469. package/src/harness/types.ts +64 -22
  470. package/src/harness/usage-accumulator.ts +2 -2
  471. package/src/harness-adapters.ts +5 -4
  472. package/src/interceptors/__tests__/run-credential-activity.test.ts +133 -0
  473. package/src/interceptors/run-credential-activity.ts +67 -0
  474. package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
  475. package/src/middleware/approval-gate.ts +7 -74
  476. package/src/middleware/cost-advisory.ts +3 -3
  477. package/src/middleware/index.ts +1 -1
  478. package/src/runner-manager.ts +14 -4
  479. package/src/shared/__tests__/approval-policy.test.ts +45 -0
  480. package/src/shared/__tests__/args-preview.test.ts +40 -20
  481. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  482. package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
  483. package/src/shared/__tests__/attachment-zip.test.ts +1 -1
  484. package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
  485. package/src/shared/__tests__/channel-attachment.test.ts +12 -0
  486. package/src/shared/__tests__/cost-guard.test.ts +1 -1
  487. package/src/shared/__tests__/exact-apply.test.ts +2 -1
  488. package/src/shared/__tests__/memory-attachment.test.ts +17 -0
  489. package/src/shared/__tests__/persist-decision.test.ts +19 -33
  490. package/src/shared/__tests__/prompt-sections.test.ts +1 -1
  491. package/src/shared/__tests__/run-credential.test.ts +111 -0
  492. package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
  493. package/src/shared/__tests__/status-offload.test.ts +1 -1
  494. package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
  495. package/src/shared/__tests__/todos.test.ts +1 -1
  496. package/src/shared/__tests__/tool-row.test.ts +1 -1
  497. package/src/shared/activity-input.ts +21 -0
  498. package/src/shared/approval-policy.ts +95 -0
  499. package/src/shared/args-preview.ts +51 -42
  500. package/src/shared/attachment-resolver.ts +4 -4
  501. package/src/shared/attachment-zip.ts +2 -2
  502. package/src/shared/channel-attachment.ts +14 -6
  503. package/src/shared/cost-guard.ts +2 -2
  504. package/src/shared/exact-apply.ts +1 -1
  505. package/src/shared/execution-context.ts +2 -2
  506. package/src/shared/extract-structured-output.ts +2 -2
  507. package/src/shared/filereview/__tests__/capture.test.ts +9 -5
  508. package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
  509. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
  510. package/src/shared/filereview/cas-touched.ts +2 -2
  511. package/src/shared/filereview/progress.ts +13 -0
  512. package/src/shared/heartbeat.ts +1 -1
  513. package/src/shared/llm-backend.ts +0 -4
  514. package/src/shared/memory-attachment.ts +22 -10
  515. package/src/shared/model-error.ts +1 -2
  516. package/src/shared/persist-decision.ts +19 -28
  517. package/src/shared/prompt-sections.ts +4 -4
  518. package/src/shared/run-credential-store.ts +45 -0
  519. package/src/shared/run-credential.ts +70 -0
  520. package/src/shared/skill-resolver.ts +3 -3
  521. package/src/shared/status-offload.ts +2 -2
  522. package/src/shared/streaming-scheduler.ts +8 -13
  523. package/src/shared/subagent-rows.ts +2 -2
  524. package/src/shared/synthesized-attachment.ts +38 -3
  525. package/src/shared/todos.ts +3 -3
  526. package/src/shared/tool-row.ts +38 -2
  527. package/src/shared/worker-shutdown.ts +1 -1
  528. package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
  529. package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
  530. package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
  531. package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
  532. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
  533. package/src/shared/workspace/provisioner.ts +1 -1
  534. package/src/shared/workspace/session-provision.ts +1 -1
  535. package/src/shared/workspace/sources/empty.ts +2 -2
  536. package/src/shared/workspace/sources/git.ts +3 -4
  537. package/src/shared/workspace/sources/local-path.ts +5 -6
  538. package/src/shared/workspace/stigmer-link.ts +1 -1
  539. package/src/shared/workspace/types.ts +2 -5
  540. package/src/shared/workspace/writeback-coordinator.ts +23 -12
  541. package/src/worker.ts +15 -3
  542. package/src/workflow-source.ts +15 -0
  543. package/src/workflows/__tests__/run-credential-interceptor.test.ts +178 -0
  544. package/src/workflows/execute-from-execution.ts +17 -0
  545. package/src/workflows/index.ts +5 -3
  546. package/src/workflows/interceptors/run-credential.ts +101 -0
  547. package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
  548. package/dist/activities/execute-cursor/delta-enricher.js +0 -265
  549. package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
  550. package/dist/activities/execute-cursor/message-translator.js +0 -2040
  551. package/dist/activities/execute-cursor/message-translator.js.map +0 -1
  552. package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
  553. package/dist/activities/execute-cursor/todo-tracker.js +0 -80
  554. package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
  555. package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
  556. package/dist/activities/execute-deep-agent/execution-state.js +0 -68
  557. package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
  558. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
  559. package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
  560. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
  561. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
  562. package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
  563. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
  564. package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
  565. package/dist/activities/execute-deep-agent/v3-events.js +0 -35
  566. package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
  567. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
  568. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
  569. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
  570. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
  571. package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
  572. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
  573. package/dist/shared/execution-status-writer.d.ts +0 -31
  574. package/dist/shared/execution-status-writer.js +0 -43
  575. package/dist/shared/execution-status-writer.js.map +0 -1
  576. package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
  577. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
  578. package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
  579. package/src/activities/execute-cursor/delta-enricher.ts +0 -307
  580. package/src/activities/execute-cursor/message-translator.ts +0 -2319
  581. package/src/activities/execute-cursor/todo-tracker.ts +0 -91
  582. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
  583. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
  584. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
  585. package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
  586. package/src/activities/execute-deep-agent/execution-state.ts +0 -78
  587. package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
  588. package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
  589. package/src/activities/execute-deep-agent/v3-events.ts +0 -153
  590. package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
  591. package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
  592. package/src/shared/execution-status-writer.ts +0 -56
@@ -42,6 +42,18 @@
42
42
  * the SDK double (`ScriptedSdkOptions`); an SDK-side cancel or a mid-stream
43
43
  * wedge as an `effect` step on the run. Nothing here is a switch in production
44
44
  * code — every knob is a value the production path already reads.
45
+ *
46
+ * Two postures, two entries, one turn runner. `beginCursorScenario` is the
47
+ * hermetic posture: the SDK doubled by the scenario file's `vi.mock`, the
48
+ * clock scripted, goldens byte-stable. `beginLiveCursorScenario` is the live
49
+ * posture (#1097's live-run gate): the scenario file mocks ONLY the
50
+ * client, the real `@cursor/sdk` runs under the real activity on the real
51
+ * clock with a real member key, and what the activity persists is read back
52
+ * from the same record. A live scenario therefore has no `sdk` and no `clock`
53
+ * — the type says which posture a file is in — and `runCursorTurn` reads only
54
+ * what both have. The registry fixture's `live` pass-through and the
55
+ * environment's `eventRecordingDir` are the live posture's two other
56
+ * seams, each on the module that owns the concern.
45
57
  */
46
58
 
47
59
  import { execFileSync } from "node:child_process";
@@ -216,20 +228,27 @@ export function resetCursorModuleState(): void {
216
228
  _resetRegistryCache();
217
229
  }
218
230
 
219
- export interface CursorScenario {
231
+ /** What both postures share: the environment, the record the activity persists into, the runner's `Config`. */
232
+ export interface CursorScenarioBase {
220
233
  readonly env: HermeticEnvironment;
221
- readonly clock: ScriptedClock;
222
234
  readonly record: ExecutionRecord;
223
- readonly sdk: ScriptedCursorSdk;
224
235
  /** The runner this scenario runs on: the OSS posture plus the scenario's knobs. */
225
236
  readonly config: Config;
226
237
  }
227
238
 
228
- export interface CursorScenarioOptions {
229
- readonly env: HermeticEnvironment;
239
+ /** The hermetic posture: the SDK double and the scripted clock beside the shared three. */
240
+ export interface CursorScenario extends CursorScenarioBase {
230
241
  readonly clock: ScriptedClock;
242
+ readonly sdk: ScriptedCursorSdk;
243
+ }
244
+
245
+ /** The live posture (header): the shared three and nothing doubled but the client. */
246
+ export type LiveCursorScenario = CursorScenarioBase;
247
+
248
+ /** The options both postures take. */
249
+ interface CursorScenarioBaseOptions {
250
+ readonly env: HermeticEnvironment;
231
251
  readonly record: ExecutionRecord;
232
- readonly sdk: ScriptedSdkOptions;
233
252
  /**
234
253
  * Control-plane facets the scenario opts INTO, or faults it injects, over
235
254
  * the record's everyday answers (`ExecutionRecord.client`): a rejecting
@@ -245,21 +264,50 @@ export interface CursorScenarioOptions {
245
264
  readonly config?: Partial<Config>;
246
265
  }
247
266
 
248
- /** Bind the record and the SDK for a scenario; resets the harness caches first. */
249
- export function beginCursorScenario(options: CursorScenarioOptions): CursorScenario {
267
+ export interface CursorScenarioOptions extends CursorScenarioBaseOptions {
268
+ readonly clock: ScriptedClock;
269
+ readonly sdk: ScriptedSdkOptions;
270
+ }
271
+
272
+ export interface LiveCursorScenarioOptions extends CursorScenarioBaseOptions {
273
+ /** The real member key the real SDK authenticates with; becomes `config.cursorApiKey`. */
274
+ readonly apiKey: string;
275
+ }
276
+
277
+ /**
278
+ * What every scenario begins with: the harness caches dropped, the record
279
+ * bound as the control plane the activity will talk to, the OSS `Config`
280
+ * over the environment with the scenario's knobs laid on top.
281
+ */
282
+ function beginScenarioBase(options: CursorScenarioBaseOptions): CursorScenarioBase {
250
283
  resetCursorModuleState();
251
- const sdk = new ScriptedCursorSdk(options.sdk);
252
- bindScriptedSdk(sdk);
253
284
  bindHermeticClient(options.record.client(options.clientOverrides));
254
285
  return {
255
286
  env: options.env,
256
- clock: options.clock,
257
287
  record: options.record,
258
- sdk,
259
288
  config: { ...hermeticCursorConfig(options.env), ...options.config },
260
289
  };
261
290
  }
262
291
 
292
+ /** Bind the record and the SDK double for a hermetic scenario; resets the harness caches first. */
293
+ export function beginCursorScenario(options: CursorScenarioOptions): CursorScenario {
294
+ const base = beginScenarioBase(options);
295
+ const sdk = new ScriptedCursorSdk(options.sdk);
296
+ bindScriptedSdk(sdk);
297
+ return { ...base, clock: options.clock, sdk };
298
+ }
299
+
300
+ /**
301
+ * Bind the record for a live scenario; resets the harness caches first. No
302
+ * SDK double is built or bound — the scenario file must NOT mock `@cursor/sdk`
303
+ * — and no clock is installed. The key lands on the `Config` exactly where
304
+ * the OSS runner's direct mode reads it (`turn-setup.ts`, `config.cursorApiKey`).
305
+ */
306
+ export function beginLiveCursorScenario(options: LiveCursorScenarioOptions): LiveCursorScenario {
307
+ const base = beginScenarioBase(options);
308
+ return { ...base, config: { ...base.config, cursorApiKey: options.apiKey } };
309
+ }
310
+
263
311
  export interface CursorTurnOptions {
264
312
  /** Empty for a first invocation; the agent id for a HITL reinvocation. */
265
313
  readonly threadId?: string;
@@ -269,13 +317,15 @@ export interface CursorTurnOptions {
269
317
  }
270
318
 
271
319
  /**
272
- * Run ONE `ExecuteCursor` invocation for the scenario: the real Cursor
273
- * adapter under the real turn runtime, as the composition roots wire them.
274
- * Built per invocation (the registry constructs its client, which is the one
275
- * bound at `beginCursorScenario`; the adapter boots on the scenario's config).
320
+ * Run ONE `ExecuteCursor` invocation for the scenario — either posture: the
321
+ * real Cursor adapter under the real turn runtime, as the composition roots
322
+ * wire them. Built per invocation (the registry constructs its client, which
323
+ * is the one bound at `begin*CursorScenario`; the adapter boots on the
324
+ * scenario's config). Reads only the record and the config, which both
325
+ * postures have.
276
326
  */
277
327
  export async function runCursorTurn(
278
- scenario: CursorScenario,
328
+ scenario: CursorScenarioBase,
279
329
  options: CursorTurnOptions = {},
280
330
  ): Promise<ActivityInvocation> {
281
331
  // Imported lazily so the scenario file's `vi.mock` declarations are in
@@ -15,7 +15,12 @@
15
15
  * So a turn is a SCRIPT of ordered steps, one of four kinds:
16
16
  *
17
17
  * - `event(SDKMessage)` — yielded from `stream()`
18
- * - `delta(update)` — fired through `onDelta` (usage, `turn-ended`)
18
+ * - `delta(update)` — fired through `onDelta`: any `InteractionUpdate`
19
+ * (the `turn-ended` usage the loop prices; the
20
+ * tool-call timings, shell output and completion
21
+ * status the transcript folds — #1097 widened
22
+ * the step from `turn-ended` alone so the delta
23
+ * channel has an end-to-end net)
19
24
  * - `effect(fn)` — the side effect the SDK would have performed
20
25
  * (run the real hook, write a workspace file,
21
26
  * cancel the activity from the outside)
@@ -25,10 +30,10 @@
25
30
  * (`ScriptStep`, driven in order), applied to the SDK's event surface.
26
31
  *
27
32
  * Typing: `SDKMessage`, `Run`, `RunResult`, `SDKAgent` and the delta channel's
28
- * `TurnEndedUpdate` are the SDK's own types (`@cursor/sdk` 1.0.31, concrete in
29
- * `messages.d.ts` / `run.d.ts` / `agent.d.ts` / the vendored `delta-types`),
33
+ * `InteractionUpdate` are the SDK's own types (`@cursor/sdk` 1.0.31, concrete
34
+ * in `messages.d.ts` / `run.d.ts` / `agent.d.ts` / the vendored `delta-types`),
30
35
  * so a script that drifts from the real event shape fails `tsc`. (At 1.0.13
31
- * the delta types resolved to `any` and the one delta this double emits was
36
+ * the delta types resolved to `any` and the one delta this double emitted was
32
37
  * typed locally; stigmer/stigmer#1053 closed that gap.)
33
38
  *
34
39
  * Cancellation: `run.cancel()` is how the harness stops a turn (first denial,
@@ -48,6 +53,7 @@
48
53
  import type {
49
54
  AgentUsage,
50
55
  GetUsageOptions,
56
+ InteractionUpdate,
51
57
  ModelSelection,
52
58
  Run,
53
59
  RunOperation,
@@ -73,7 +79,7 @@ export interface EffectContext {
73
79
 
74
80
  export type ScriptStep =
75
81
  | { readonly kind: "event"; readonly event: SDKMessage }
76
- | { readonly kind: "delta"; readonly update: TurnEndedUpdate }
82
+ | { readonly kind: "delta"; readonly update: InteractionUpdate }
77
83
  | { readonly kind: "effect"; readonly label: string; readonly run: (ctx: EffectContext) => void | Promise<void> }
78
84
  | { readonly kind: "result"; readonly result: Omit<RunResult, "id"> };
79
85
 
@@ -85,6 +91,10 @@ export const step = {
85
91
  event(event: SDKMessage): ScriptStep {
86
92
  return { kind: "event", event };
87
93
  },
94
+ /** Any delta the SDK fires through `onDelta` between stream events: tool-call timings, shell output, a completion's status. */
95
+ delta(update: InteractionUpdate): ScriptStep {
96
+ return { kind: "delta", update };
97
+ },
88
98
  /** The `turn-ended` delta `turn-stream.ts` prices; the SDK's shape, all four counts stated. */
89
99
  turnEnded(usage: NonNullable<TurnEndedUpdate["usage"]>): ScriptStep {
90
100
  return { kind: "delta", update: { type: "turn-ended", usage } };
@@ -130,6 +140,10 @@ export function sdkEvents(agentId: string, runId: string) {
130
140
  status(status: "CREATING" | "RUNNING" | "FINISHED" | "ERROR" | "CANCELLED" | "EXPIRED", message?: string): SDKMessage {
131
141
  return { type: "status", ...base, status, message };
132
142
  },
143
+ /** The SDK's `task` event: a status line about the run in the agent's own voice, which the transcript shows as a SYSTEM message. */
144
+ task(text: string, status?: string): SDKMessage {
145
+ return { type: "task", ...base, text, status };
146
+ },
133
147
  };
134
148
  }
135
149
 
@@ -1,5 +1,6 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins file-edit HITL fix #6 (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins content-exact approval identity: approving
3
+ * one edit never lets a DIFFERENT edit to the same path ride the grant.
3
4
  *
4
5
  * Unit tests for the Cursor-harness HITL approval gate logic.
5
6
  *
@@ -1,5 +1,6 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins file-edit HITL fix #6 (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins content-exact approval identity: approving
3
+ * one edit never lets a DIFFERENT edit to the same path ride the grant.
3
4
  *
4
5
  * Resume-grant identity round-trip — the H1 lock.
5
6
  *
@@ -21,7 +22,7 @@
21
22
  * - the resume grant via {@link buildApprovalGrants} -> parseArgs(argsPreview)
22
23
  * (the JSON-string preview only).
23
24
  * They agree today only because both derive from the same stream `event.args`.
24
- * This suite drives the REAL stream path ({@link buildToolCallProto}) so any
25
+ * This suite drives the REAL stream path (the translator into the builder) so any
25
26
  * future change that lets the dual path diverge fails here, loudly, per category.
26
27
  *
27
28
  * Deterministic; no Cursor API key, no bash. The hook-side half of the equality
@@ -42,11 +43,9 @@ import {
42
43
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
43
44
  import type { SDKMessage } from "@cursor/sdk";
44
45
 
45
- import {
46
- buildToolCallProto,
47
- reconcileDeniedToolCalls,
48
- toolCallIdentityToken,
49
- } from "../message-translator.js";
46
+ import { reconcileDeniedToolCalls } from "../boundary-rows.js";
47
+ import { builderOver, foldCursorEvents } from "../__test-utils__/fold.js";
48
+ import { toolCallIdentityToken } from "../approval-state.js";
50
49
  import {
51
50
  buildApprovalGrants,
52
51
  buildApprovalState,
@@ -96,7 +95,7 @@ function mcpEvent(
96
95
  * and return the two identities that must be equal: the token the hook recorded
97
96
  * when it denied the gated call, and the grant token a resume mints after the
98
97
  * user approves it. Mirrors the activity's real sequence:
99
- * buildToolCallProto (stream) -> deny overlay (reconcileDeniedToolCalls) ->
98
+ * translator + builder (stream) -> deny overlay (reconcileDeniedToolCalls) ->
100
99
  * persist APPROVE -> reconstructAdjudicatedApprovals -> buildApprovalGrants.
101
100
  */
102
101
  async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Promise<{
@@ -105,7 +104,7 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
105
104
  resumeStateToken: string | undefined;
106
105
  grant: ApprovalGrant;
107
106
  }> {
108
- const tc = buildToolCallProto(event);
107
+ const tc = foldCursorEvents([event]).rows()[0];
109
108
 
110
109
  // The gated turn: the hook denies the call, recording its identity token. The
111
110
  // runner's overlay (reconcileDeniedToolCalls) flips the same call to
@@ -120,7 +119,8 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
120
119
  toolCalls: [tc],
121
120
  });
122
121
  const ledger: DeniedLedgerEntry[] = [{ toolName: tc.name, token: denialToken }];
123
- const denied = await reconcileDeniedToolCalls([msg], ledger);
122
+ const messages: AgentMessage[] = [msg];
123
+ const denied = await reconcileDeniedToolCalls(messages, builderOver(messages), ledger);
124
124
  expect(denied, "the overlay must match the denial token and surface the gate").toHaveLength(1);
125
125
 
126
126
  // The user approves; the backend persists the decision on the tool call.
@@ -130,7 +130,6 @@ async function roundTrip(event: Extract<SDKMessage, { type: "tool_call" }>): Pro
130
130
  // transcript (pending_approvals is already cleared by this point) and mint the
131
131
  // grants the next turn's hook reads. The content digest threads through so the
132
132
  // grant reproduces the content-exact denial identity.
133
- const messages: AgentMessage[] = [msg];
134
133
  const { pendingApprovals, decisions, contentDigests } = reconstructAdjudicatedApprovals(messages);
135
134
  const grants = buildApprovalGrants(pendingApprovals, decisions, contentDigests);
136
135
  expect(grants, "an approved tool must yield exactly one grant").toHaveLength(1);
@@ -234,12 +233,8 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
234
233
  // The exact bug this change fixes: approving the rename must NOT authorize
235
234
  // the TODO edit. They share a path (same coarse token) but differ in content,
236
235
  // so the content-exact identity distinguishes them.
237
- const rename = buildToolCallProto(
238
- builtInEvent("c1", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" }),
239
- );
240
- const todo = buildToolCallProto(
241
- builtInEvent("c2", "edit", { path: "/work/notes.md", old_string: "", new_string: "## TODO\n" }),
242
- );
236
+ const rename = foldCursorEvents([builtInEvent("c1", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" })]).rows()[0];
237
+ const todo = foldCursorEvents([builtInEvent("c2", "edit", { path: "/work/notes.md", old_string: "", new_string: "## TODO\n" })]).rows()[0];
243
238
  const renameToken = toolCallIdentityToken(rename);
244
239
  const todoToken = toolCallIdentityToken(todo);
245
240
 
@@ -252,9 +247,7 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
252
247
  );
253
248
  // Re-issuing the SAME rename content reproduces its identity (identical
254
249
  // re-attempt is allowed; a drifted one re-gates).
255
- const renameAgain = buildToolCallProto(
256
- builtInEvent("c3", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" }),
257
- );
250
+ const renameAgain = foldCursorEvents([builtInEvent("c3", "edit", { path: "/work/notes.md", old_string: "Planton Cloud", new_string: "Planton" })]).rows()[0];
258
251
  expect(toolCallIdentityToken(renameAgain)).toBe(renameToken);
259
252
  });
260
253
 
@@ -263,7 +256,7 @@ describe("Cursor resume-grant identity round-trip (H1 lock)", () => {
263
256
  event: Extract<SDKMessage, { type: "tool_call" }>,
264
257
  action: ApprovalAction,
265
258
  ): AgentMessage {
266
- const tc = buildToolCallProto(event);
259
+ const tc = foldCursorEvents([event]).rows()[0];
267
260
  tc.status = ToolCallStatus.TOOL_CALL_WAITING_APPROVAL;
268
261
  tc.requiresApproval = true;
269
262
  tc.approvalAction = action;
@@ -544,7 +544,7 @@ describe("attachments on a resumed turn (T04 — the mid-session WhatsApp case)"
544
544
  ],
545
545
  }),
546
546
  );
547
- // The size precedes the disclosure (the shared line, S3 M5 Q-M5-3).
547
+ // The size precedes the disclosure (the shared line, since #1096).
548
548
  expect(prompt).toContain(
549
549
  "- `.stigmer/inputs/report-2.pdf` (1024 bytes) (renamed from duplicate 'report.pdf')",
550
550
  );
@@ -778,8 +778,8 @@ describe("buildReinvocationPrompt", () => {
778
778
  expect(prompt).toContain("Continue the rest of the task");
779
779
  });
780
780
 
781
- it("names a REJECTED action as a refusal, apart from the skipped ones, and still continues the task (stigmer#197; S3 M1)", () => {
782
- // A REJECT denies the tool and the run continues; before S3 M1 the
781
+ it("names a REJECTED action as a refusal, apart from the skipped ones, and still continues the task (stigmer#197)", () => {
782
+ // A REJECT denies the tool and the run continues; before #1096 the
783
783
  // runtime failed the reinvocation before this prompt was ever built, so
784
784
  // the prompt had no REJECT arm.
785
785
  const decisions = new Map<string, ApprovalAction>([
@@ -1,5 +1,6 @@
1
1
  /**
2
- * @regression file-hitl-phase0 — pins file-edit HITL fix #6 (see _projects/2026-06/20260630.01.file-change-hitl-redesign/tasks/T01_3_regression-manifest.md)
2
+ * @regression file-hitl-phase0 — pins content-exact approval identity: approving
3
+ * one edit never lets a DIFFERENT edit to the same path ride the grant.
3
4
  *
4
5
  * Slice D — the Cursor grant token / fingerprint as the substrate-coarsened
5
6
  * projection of the shared canonical action.
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The Cursor event recorder's contract (`cursor-event-recorder.ts`): off when
3
+ * no directory is named; both SDK channels in ONE file under ONE arrival
4
+ * counter, each line saying which channel it came from; the file named by the
5
+ * execution; a cyclic payload recorded as a marker rather than failing the
6
+ * flush. The native recorder's `v3-event-recorder.test.ts` is the sibling.
7
+ *
8
+ * The ordering arm is the reason the recorder exists in this shape: a delta
9
+ * that arrives between two stream events must read between them in the file,
10
+ * because "does `tool-call-completed` precede the stream's own completion" is
11
+ * a question only the arrival order can answer.
12
+ */
13
+ import { describe, it, expect, beforeEach } from "vitest";
14
+ import { mkdtemp, readFile, readdir } from "node:fs/promises";
15
+ import { join } from "node:path";
16
+ import { tmpdir } from "node:os";
17
+ import type { InteractionUpdate, SDKMessage } from "@cursor/sdk";
18
+ import { createCursorEventRecorder } from "../cursor-event-recorder.js";
19
+
20
+ /** A stream event carrying only what the recorder reads; the rest is payload. */
21
+ function streamEvent(type: string, extra: Record<string, unknown> = {}): SDKMessage {
22
+ return { type, agent_id: "agent-1", run_id: "run-1", ...extra } as unknown as SDKMessage;
23
+ }
24
+
25
+ function delta(type: string, extra: Record<string, unknown> = {}): InteractionUpdate {
26
+ return { type, ...extra } as unknown as InteractionUpdate;
27
+ }
28
+
29
+ interface RecordedLine {
30
+ readonly seq: number;
31
+ readonly capturedAt: string;
32
+ readonly channel: "stream" | "delta";
33
+ readonly type: string;
34
+ readonly agent_id?: string;
35
+ readonly run_id?: string;
36
+ readonly event?: Record<string, unknown>;
37
+ readonly update?: Record<string, unknown>;
38
+ }
39
+
40
+ async function readLines(dir: string, executionId: string): Promise<RecordedLine[]> {
41
+ const content = await readFile(join(dir, `${executionId}.cursor-events.jsonl`), "utf-8");
42
+ return content
43
+ .split("\n")
44
+ .filter((line) => line.length > 0)
45
+ .map((line) => JSON.parse(line) as RecordedLine);
46
+ }
47
+
48
+ describe("createCursorEventRecorder", () => {
49
+ it("returns undefined when no directory is named (recording off)", () => {
50
+ expect(createCursorEventRecorder("exec-1", undefined)).toBeUndefined();
51
+ expect(createCursorEventRecorder("exec-1", "")).toBeUndefined();
52
+ });
53
+
54
+ it("returns a recorder with both channels and a flush when a directory is named", () => {
55
+ const recorder = createCursorEventRecorder("exec-1", "/tmp/unused");
56
+ expect(recorder).toBeDefined();
57
+ expect(recorder!.record).toBeInstanceOf(Function);
58
+ expect(recorder!.recordDelta).toBeInstanceOf(Function);
59
+ expect(recorder!.flush).toBeInstanceOf(Function);
60
+ });
61
+ });
62
+
63
+ describe("CursorEventRecorder", () => {
64
+ let dir: string;
65
+
66
+ beforeEach(async () => {
67
+ dir = await mkdtemp(join(tmpdir(), "cursor-recorder-test-"));
68
+ });
69
+
70
+ it("flush writes nothing when nothing was recorded", async () => {
71
+ const recorder = createCursorEventRecorder("exec-empty", dir)!;
72
+ await recorder.flush();
73
+ expect(await readdir(dir)).toHaveLength(0);
74
+ });
75
+
76
+ it("sequences both channels in ONE file in arrival order, each line naming its channel", async () => {
77
+ const recorder = createCursorEventRecorder("exec-order", dir)!;
78
+
79
+ recorder.record(streamEvent("tool_call", { subtype: "started", call_id: "c1" }));
80
+ recorder.recordDelta(delta("shell-output-delta", { event: { chunk: "hook probe\n" } }));
81
+ recorder.recordDelta(delta("tool-call-completed", { toolCall: { id: "c1" } }));
82
+ recorder.record(streamEvent("tool_call", { subtype: "completed", call_id: "c1" }));
83
+ recorder.record(streamEvent("result"));
84
+
85
+ await recorder.flush();
86
+ const lines = await readLines(dir, "exec-order");
87
+
88
+ expect(lines.map((l) => l.seq)).toEqual([0, 1, 2, 3, 4]);
89
+ expect(lines.map((l) => `${l.channel}:${l.type}`)).toEqual([
90
+ "stream:tool_call",
91
+ "delta:shell-output-delta",
92
+ "delta:tool-call-completed",
93
+ "stream:tool_call",
94
+ "stream:result",
95
+ ]);
96
+ for (const line of lines) expect(line.capturedAt).toBeTruthy();
97
+ });
98
+
99
+ it("a stream line carries the event's agent and run ids and the whole event; a delta line the whole update", async () => {
100
+ const recorder = createCursorEventRecorder("exec-shape", dir)!;
101
+
102
+ recorder.record(streamEvent("assistant", { content: "hi" }));
103
+ recorder.recordDelta(delta("turn-ended", { usage: { inputTokens: 12 } }));
104
+
105
+ await recorder.flush();
106
+ const [stream, deltaLine] = await readLines(dir, "exec-shape");
107
+
108
+ expect(stream!.agent_id).toBe("agent-1");
109
+ expect(stream!.run_id).toBe("run-1");
110
+ expect(stream!.event).toMatchObject({ type: "assistant", content: "hi" });
111
+ expect(stream!.update).toBeUndefined();
112
+
113
+ expect(deltaLine!.update).toEqual({ type: "turn-ended", usage: { inputTokens: 12 } });
114
+ expect(deltaLine!.event).toBeUndefined();
115
+ expect(deltaLine!.agent_id).toBeUndefined();
116
+ });
117
+
118
+ it("names the file by execution id and creates the directory if it does not exist", async () => {
119
+ const nested = join(dir, "nested", "deep");
120
+ const recorder = createCursorEventRecorder("exec-mkdir", nested)!;
121
+
122
+ recorder.record(streamEvent("system"));
123
+ await recorder.flush();
124
+
125
+ expect(await readdir(nested)).toEqual(["exec-mkdir.cursor-events.jsonl"]);
126
+ });
127
+
128
+ it("records a cyclic payload as a serialization marker instead of failing the flush", async () => {
129
+ const recorder = createCursorEventRecorder("exec-cyclic", dir)!;
130
+
131
+ const cyclic: Record<string, unknown> = { type: "custom", a: 1 };
132
+ cyclic.self = cyclic;
133
+ recorder.record(cyclic as unknown as SDKMessage);
134
+
135
+ await recorder.flush();
136
+ const [line] = await readLines(dir, "exec-cyclic");
137
+
138
+ expect(line!.type).toBe("custom");
139
+ expect(line!.event).toMatchObject({ _serializationError: true });
140
+ expect((line!.event as { keys: string[] }).keys).toContain("a");
141
+ });
142
+ });
@@ -1,11 +1,22 @@
1
1
  /**
2
- * Test that reproduces the desktop runner's EXACT execution path.
2
+ * Live probe: which of the SDK's calls a `globalThis.fetch` interceptor can
3
+ * see. A fetch wrapper that notes any call to a cursor.sh / cursor.com URL is
4
+ * installed, then `Agent.create()` runs (local mode, no model named).
3
5
  *
4
- * Simulates proxy mode: fetch interceptor installed, apiKey="proxy-managed",
5
- * to verify whether the proxy rewriting actually intercepts @cursor/sdk calls.
6
+ * What the one arm proves: `Agent.create()` completes WITHOUT a global-fetch
7
+ * call to a Cursor URL — its transport is connect-node over Node's HTTP/2, so
8
+ * a fetch-level interceptor alone cannot rewrite it. That is why the adapter
9
+ * installs BOTH interceptors in proxy mode (`fetch-interceptor.ts` and
10
+ * `http2-interceptor.ts`). Measured true at SDK 1.0.31 on 2026-09-16 (#1097's
11
+ * live run, 1/1).
6
12
  *
7
- * Expected result: THIS TEST WILL FAIL because @cursor/sdk uses connect-node
8
- * (Node.js native HTTP), not globalThis.fetch. The fetch interceptor never fires.
13
+ * What it does NOT prove: that the fetch interceptor is useless. A reading of
14
+ * the 1.0.31 bundle the same day found the SDK's cloud-api client and its
15
+ * token exchange on global `fetch`, on paths this arm never exercises; the
16
+ * fetch interceptor exists for those.
17
+ *
18
+ * Skipped without `CURSOR_API_KEY`; the suite never runs it. Run it by hand:
19
+ * CURSOR_API_KEY=<key> npx vitest run src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts
9
20
  */
10
21
 
11
22
  import { describe, it, expect, beforeAll, afterAll } from "vitest";
@@ -39,7 +50,7 @@ describeWithCursorKey("Fetch Interceptor vs Connect-Node Transport", () => {
39
50
  globalThis.fetch = originalFetch;
40
51
  });
41
52
 
42
- it("Agent.create() does NOT go through globalThis.fetch (proving interceptor is useless)", async () => {
53
+ it("Agent.create() completes without a globalThis.fetch call to a Cursor URL", async () => {
43
54
  const { Agent } = await import("@cursor/sdk");
44
55
  const { SqliteLocalAgentStore } = await import("@cursor/sdk/sqlite");
45
56
 
@@ -58,8 +69,8 @@ describeWithCursorKey("Fetch Interceptor vs Connect-Node Transport", () => {
58
69
  expect(agent.agentId).toBeTruthy();
59
70
  console.log(`Agent created: ${agent.agentId}, interceptCalled=${interceptCalled}`);
60
71
 
61
- // This assertion proves the fetch interceptor pattern is broken:
62
- // connect-node uses Node.js http module, NOT globalThis.fetch
72
+ // The create path is connect-node over Node's HTTP/2, not globalThis.fetch;
73
+ // see the header for what this does and does not say about proxy mode.
63
74
  expect(interceptCalled).toBe(false);
64
75
  }, 30_000);
65
76
  });
@@ -1,13 +1,15 @@
1
1
  /**
2
- * Minimal smoke test to verify Cursor SDK authentication works with a real API key.
2
+ * Live smoke: the Cursor SDK authenticates and completes a round trip on a
3
+ * real member key. Three arms, each isolating one fact:
4
+ * 1. `Agent.create()` with a model named succeeds — the key is valid;
5
+ * 2. `agent.send()` runs to a completed result — the agent executes and the
6
+ * transport completes the round trip;
7
+ * 3. `Agent.create()` with no model named succeeds — the catalog default
8
+ * resolves.
3
9
  *
4
- * Tests three things in isolation:
5
- * 1. Agent.create() succeeds (proves the API key is valid)
6
- * 2. agent.send() produces a response (proves the agent can execute)
7
- * 3. The connect-node transport works end-to-end
8
- *
9
- * Run with: CURSOR_API_KEY=<key> npx tsx --test this-file.ts
10
- * Or via the test script: npm run test:cursor-auth
10
+ * Skipped without `CURSOR_API_KEY`; the suite never runs it. Run it by hand:
11
+ * CURSOR_API_KEY=<key> npx vitest run src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts
12
+ * Last run green 3/3 on 2026-09-16 at SDK 1.0.31 (#1097's live run).
11
13
  */
12
14
 
13
15
  import { describe, it, expect } from "vitest";