@stigmer/runner 3.14.0 → 3.15.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 (331) hide show
  1. package/dist/.build-fingerprint +1 -1
  2. package/dist/__test-utils__/execution-record-fixture.d.ts +47 -0
  3. package/dist/__test-utils__/execution-record-fixture.js +68 -0
  4. package/dist/__test-utils__/execution-record-fixture.js.map +1 -0
  5. package/dist/__test-utils__/harness-contract/types.d.ts +166 -0
  6. package/dist/__test-utils__/harness-contract/types.js +49 -0
  7. package/dist/__test-utils__/harness-contract/types.js.map +1 -0
  8. package/dist/__test-utils__/hermetic-activity.d.ts +268 -0
  9. package/dist/__test-utils__/hermetic-activity.js +385 -0
  10. package/dist/__test-utils__/hermetic-activity.js.map +1 -0
  11. package/dist/__test-utils__/mock-client.d.ts +13 -0
  12. package/dist/__test-utils__/mock-client.js +45 -0
  13. package/dist/__test-utils__/mock-client.js.map +1 -0
  14. package/dist/__test-utils__/mock-workspace.d.ts +15 -0
  15. package/dist/__test-utils__/mock-workspace.js +21 -0
  16. package/dist/__test-utils__/mock-workspace.js.map +1 -0
  17. package/dist/__test-utils__/model-registry-fixture.d.ts +56 -0
  18. package/dist/__test-utils__/model-registry-fixture.js +66 -0
  19. package/dist/__test-utils__/model-registry-fixture.js.map +1 -0
  20. package/dist/__test-utils__/turn-input-fixture.d.ts +60 -0
  21. package/dist/__test-utils__/turn-input-fixture.js +118 -0
  22. package/dist/__test-utils__/turn-input-fixture.js.map +1 -0
  23. package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +107 -0
  24. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +344 -0
  25. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -0
  26. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +20 -0
  27. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +58 -0
  28. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
  29. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +2 -32
  30. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
  31. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +148 -0
  32. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +257 -0
  33. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -0
  34. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +183 -0
  35. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +262 -0
  36. package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -0
  37. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +138 -0
  38. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +191 -0
  39. package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -0
  40. package/dist/activities/execute-cursor/adapter.d.ts +55 -0
  41. package/dist/activities/execute-cursor/adapter.js +119 -0
  42. package/dist/activities/execute-cursor/adapter.js.map +1 -0
  43. package/dist/activities/execute-cursor/approval-state.d.ts +2 -2
  44. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  45. package/dist/activities/execute-cursor/capture-flow.d.ts +15 -30
  46. package/dist/activities/execute-cursor/capture-flow.js +17 -26
  47. package/dist/activities/execute-cursor/capture-flow.js.map +1 -1
  48. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +23 -0
  49. package/dist/activities/execute-cursor/cursor-capabilities.js +33 -0
  50. package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -0
  51. package/dist/activities/execute-cursor/cursor-mcp-config.d.ts +2 -2
  52. package/dist/activities/execute-cursor/cursor-mcp-config.js.map +1 -1
  53. package/dist/activities/execute-cursor/fetch-interceptor.d.ts +15 -25
  54. package/dist/activities/execute-cursor/fetch-interceptor.js +39 -33
  55. package/dist/activities/execute-cursor/fetch-interceptor.js.map +1 -1
  56. package/dist/activities/execute-cursor/http2-interceptor.d.ts +21 -17
  57. package/dist/activities/execute-cursor/http2-interceptor.js +38 -31
  58. package/dist/activities/execute-cursor/http2-interceptor.js.map +1 -1
  59. package/dist/activities/execute-cursor/message-translator.d.ts +28 -19
  60. package/dist/activities/execute-cursor/message-translator.js +76 -27
  61. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  62. package/dist/activities/execute-cursor/prompt-builder.d.ts +180 -11
  63. package/dist/activities/execute-cursor/prompt-builder.js +171 -0
  64. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  65. package/dist/activities/execute-cursor/rejection-capture.d.ts +3 -6
  66. package/dist/activities/execute-cursor/rejection-capture.js +5 -7
  67. package/dist/activities/execute-cursor/rejection-capture.js.map +1 -1
  68. package/dist/activities/execute-cursor/session-lifecycle.d.ts +1 -4
  69. package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
  70. package/dist/activities/execute-cursor/turn-boundary.d.ts +1 -1
  71. package/dist/activities/execute-cursor/turn-settle.d.ts +49 -0
  72. package/dist/activities/execute-cursor/turn-settle.js +507 -0
  73. package/dist/activities/execute-cursor/turn-settle.js.map +1 -0
  74. package/dist/activities/execute-cursor/turn-setup.d.ts +173 -0
  75. package/dist/activities/execute-cursor/turn-setup.js +496 -0
  76. package/dist/activities/execute-cursor/turn-setup.js.map +1 -0
  77. package/dist/activities/execute-cursor/turn-stream.d.ts +41 -71
  78. package/dist/activities/execute-cursor/turn-stream.js +70 -135
  79. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  80. package/dist/activities/execute-cursor/turn.d.ts +43 -0
  81. package/dist/activities/execute-cursor/turn.js +222 -0
  82. package/dist/activities/execute-cursor/turn.js.map +1 -0
  83. package/dist/activities/execute-cursor/usage-pricing.d.ts +38 -0
  84. package/dist/activities/execute-cursor/usage-pricing.js +50 -0
  85. package/dist/activities/execute-cursor/usage-pricing.js.map +1 -0
  86. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +1 -1
  87. package/dist/activities/execute-deep-agent/approval-file-change.js +1 -1
  88. package/dist/activities/execute-deep-agent/environment.js +1 -1
  89. package/dist/activities/execute-deep-agent/environment.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/setup.js +3 -2
  91. package/dist/activities/execute-deep-agent/setup.js.map +1 -1
  92. package/dist/activities/hydrate-workflow-execution.js +1 -1
  93. package/dist/activities/hydrate-workflow-execution.js.map +1 -1
  94. package/dist/config.d.ts +15 -0
  95. package/dist/config.js.map +1 -1
  96. package/dist/harness/capabilities.d.ts +87 -0
  97. package/dist/harness/capabilities.js +37 -0
  98. package/dist/harness/capabilities.js.map +1 -0
  99. package/dist/harness/persist-chokepoint.d.ts +74 -0
  100. package/dist/harness/persist-chokepoint.js +88 -0
  101. package/dist/harness/persist-chokepoint.js.map +1 -0
  102. package/dist/harness/registry.d.ts +106 -0
  103. package/dist/harness/registry.js +168 -0
  104. package/dist/harness/registry.js.map +1 -0
  105. package/dist/harness/run-turn.d.ts +53 -0
  106. package/dist/harness/run-turn.js +528 -0
  107. package/dist/harness/run-turn.js.map +1 -0
  108. package/dist/harness/stop-controller.d.ts +50 -0
  109. package/dist/harness/stop-controller.js +62 -0
  110. package/dist/harness/stop-controller.js.map +1 -0
  111. package/dist/harness/terminal-table.d.ts +141 -0
  112. package/dist/harness/terminal-table.js +239 -0
  113. package/dist/harness/terminal-table.js.map +1 -0
  114. package/dist/harness/turn-context.d.ts +523 -0
  115. package/dist/harness/turn-context.js +739 -0
  116. package/dist/harness/turn-context.js.map +1 -0
  117. package/dist/harness/types.d.ts +448 -0
  118. package/dist/harness/types.js +64 -0
  119. package/dist/harness/types.js.map +1 -0
  120. package/dist/harness/usage-accumulator.d.ts +68 -0
  121. package/dist/harness/usage-accumulator.js +101 -0
  122. package/dist/harness/usage-accumulator.js.map +1 -0
  123. package/dist/harness-adapters.d.ts +27 -0
  124. package/dist/harness-adapters.js +28 -0
  125. package/dist/harness-adapters.js.map +1 -0
  126. package/dist/main.js.map +1 -1
  127. package/dist/runner-manager.js +64 -48
  128. package/dist/runner-manager.js.map +1 -1
  129. package/dist/runner.d.ts +5 -4
  130. package/dist/runner.js +65 -64
  131. package/dist/runner.js.map +1 -1
  132. package/dist/shared/approval-policy.d.ts +1 -1
  133. package/dist/shared/approval-policy.js.map +1 -1
  134. package/dist/{activities/execute-cursor → shared}/attachment-resolver.d.ts +2 -2
  135. package/dist/{activities/execute-cursor → shared}/attachment-resolver.js +5 -5
  136. package/dist/shared/attachment-resolver.js.map +1 -0
  137. package/dist/{activities/execute-cursor → shared}/blueprint-resolver.d.ts +7 -5
  138. package/dist/{activities/execute-cursor → shared}/blueprint-resolver.js +3 -63
  139. package/dist/shared/blueprint-resolver.js.map +1 -0
  140. package/dist/shared/channel-attachment.d.ts +1 -1
  141. package/dist/shared/channel-attachment.js.map +1 -1
  142. package/dist/{activities/execute-cursor → shared}/cost-guard.d.ts +5 -1
  143. package/dist/{activities/execute-cursor → shared}/cost-guard.js +5 -1
  144. package/dist/shared/cost-guard.js.map +1 -0
  145. package/dist/{activities/execute-cursor → shared}/env-resolver.d.ts +1 -1
  146. package/dist/shared/env-resolver.js.map +1 -0
  147. package/dist/{activities/execute-cursor → shared}/exact-apply.d.ts +1 -1
  148. package/dist/{activities/execute-cursor → shared}/exact-apply.js +6 -6
  149. package/dist/shared/exact-apply.js.map +1 -0
  150. package/dist/shared/execution-context.d.ts +35 -0
  151. package/dist/shared/execution-context.js +38 -0
  152. package/dist/shared/execution-context.js.map +1 -0
  153. package/dist/{activities/execute-cursor → shared}/extract-structured-output.d.ts +5 -2
  154. package/dist/{activities/execute-cursor → shared}/extract-structured-output.js +9 -6
  155. package/dist/shared/extract-structured-output.js.map +1 -0
  156. package/dist/shared/filereview/capture.d.ts +1 -1
  157. package/dist/shared/filereview/capture.js +1 -1
  158. package/dist/shared/heartbeat.d.ts +13 -11
  159. package/dist/shared/heartbeat.js +14 -29
  160. package/dist/shared/heartbeat.js.map +1 -1
  161. package/dist/{activities/execute-cursor → shared}/persist-decision.d.ts +5 -2
  162. package/dist/{activities/execute-cursor → shared}/persist-decision.js +4 -1
  163. package/dist/shared/persist-decision.js.map +1 -0
  164. package/dist/{activities/execute-cursor → shared}/skill-resolver.d.ts +16 -3
  165. package/dist/{activities/execute-cursor → shared}/skill-resolver.js +12 -4
  166. package/dist/shared/skill-resolver.js.map +1 -0
  167. package/dist/shared/subagent-rows.d.ts +21 -0
  168. package/dist/shared/subagent-rows.js +34 -0
  169. package/dist/shared/subagent-rows.js.map +1 -0
  170. package/dist/shared/worker-shutdown.d.ts +43 -16
  171. package/dist/shared/worker-shutdown.js +28 -13
  172. package/dist/shared/worker-shutdown.js.map +1 -1
  173. package/dist/shared/workspace/platform-dir.d.ts +1 -1
  174. package/dist/shared/workspace/platform-dir.js +1 -1
  175. package/dist/shared/workspace/session-provision.d.ts +54 -0
  176. package/dist/{activities/execute-cursor/workspace-provision.js → shared/workspace/session-provision.js} +15 -12
  177. package/dist/shared/workspace/session-provision.js.map +1 -0
  178. package/package.json +4 -4
  179. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +325 -0
  180. package/src/__test-utils__/config-fixture.ts +63 -0
  181. package/src/__test-utils__/execution-record-fixture.ts +104 -0
  182. package/src/__test-utils__/harness-boot-order-child.ts +58 -0
  183. package/src/__test-utils__/harness-contract/contract.ts +581 -0
  184. package/src/__test-utils__/harness-contract/recording-sink.ts +107 -0
  185. package/src/__test-utils__/harness-contract/runtime-contract.ts +666 -0
  186. package/src/__test-utils__/harness-contract/scripted-adapter.ts +349 -0
  187. package/src/__test-utils__/harness-contract/types.ts +176 -0
  188. package/src/__test-utils__/hermetic-activity.ts +502 -0
  189. package/src/__test-utils__/model-registry-fixture.ts +72 -0
  190. package/src/__test-utils__/module-specifiers.ts +82 -0
  191. package/src/__test-utils__/proto-helpers.ts +25 -0
  192. package/src/__test-utils__/turn-input-fixture.ts +155 -0
  193. package/src/__tests__/harness-boot-order.test.ts +77 -0
  194. package/src/__tests__/harness-contract.test.ts +27 -0
  195. package/src/__tests__/runner-manager.test.ts +18 -0
  196. package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +102 -0
  197. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +396 -0
  198. package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +66 -0
  199. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +2 -43
  200. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +342 -0
  201. package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +368 -0
  202. package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +254 -0
  203. package/src/activities/execute-cursor/__tests__/adapter-is-temporal-free.test.ts +45 -0
  204. package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +90 -0
  205. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +7 -8
  206. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +28 -1
  207. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +1 -1
  208. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +64 -6
  209. package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +228 -0
  210. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +180 -0
  211. package/src/activities/execute-cursor/__tests__/hermetic/goldens/cost-cap.status.json +53 -0
  212. package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn1.status.json +55 -0
  213. package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn2.status.json +77 -0
  214. package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +126 -0
  215. package/src/activities/execute-cursor/__tests__/hermetic/goldens/pause.status.json +40 -0
  216. package/src/activities/execute-cursor/__tests__/hermetic/goldens/plain-turn.status.json +48 -0
  217. package/src/activities/execute-cursor/__tests__/hermetic/goldens/platform-stop.status.json +56 -0
  218. package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-fresh-agent.status.json +53 -0
  219. package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-transport-timeout.status.json +48 -0
  220. package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
  221. package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-cancelled.status.json +36 -0
  222. package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-error-non-retryable.status.json +37 -0
  223. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +38 -0
  224. package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +59 -0
  225. package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-call.status.json +68 -0
  226. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +79 -0
  227. package/src/activities/execute-cursor/__tests__/hermetic/goldens/worker-shutdown.status.json +42 -0
  228. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +170 -0
  229. package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +205 -0
  230. package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +171 -0
  231. package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +156 -0
  232. package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +286 -0
  233. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +332 -0
  234. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +193 -0
  235. package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +137 -0
  236. package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +185 -0
  237. package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +151 -0
  238. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +65 -35
  239. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -40
  240. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +171 -0
  241. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +118 -243
  242. package/src/activities/execute-cursor/__tests__/usage-pricing.test.ts +84 -0
  243. package/src/activities/execute-cursor/adapter.ts +138 -0
  244. package/src/activities/execute-cursor/approval-state.ts +2 -2
  245. package/src/activities/execute-cursor/capture-flow.ts +18 -41
  246. package/src/activities/execute-cursor/cursor-capabilities.ts +35 -0
  247. package/src/activities/execute-cursor/cursor-mcp-config.ts +2 -2
  248. package/src/activities/execute-cursor/fetch-interceptor.ts +48 -45
  249. package/src/activities/execute-cursor/http2-interceptor.ts +47 -34
  250. package/src/activities/execute-cursor/message-translator.ts +90 -45
  251. package/src/activities/execute-cursor/prompt-builder.ts +327 -12
  252. package/src/activities/execute-cursor/rejection-capture.ts +5 -12
  253. package/src/activities/execute-cursor/session-lifecycle.ts +1 -5
  254. package/src/activities/execute-cursor/turn-boundary.ts +1 -1
  255. package/src/activities/execute-cursor/turn-settle.ts +601 -0
  256. package/src/activities/execute-cursor/turn-setup.ts +645 -0
  257. package/src/activities/execute-cursor/turn-stream.ts +84 -210
  258. package/src/activities/execute-cursor/turn.ts +240 -0
  259. package/src/activities/execute-cursor/usage-pricing.ts +67 -0
  260. package/src/activities/execute-deep-agent/approval-file-change.ts +1 -1
  261. package/src/activities/execute-deep-agent/environment.ts +1 -1
  262. package/src/activities/execute-deep-agent/setup.ts +3 -2
  263. package/src/activities/hydrate-workflow-execution.ts +1 -1
  264. package/src/config.ts +13 -0
  265. package/src/harness/__tests__/import-direction.test.ts +168 -0
  266. package/src/harness/__tests__/persist-chokepoint.test.ts +146 -0
  267. package/src/harness/__tests__/registry.test.ts +168 -0
  268. package/src/harness/__tests__/run-turn.test.ts +165 -0
  269. package/src/harness/__tests__/stop-controller.test.ts +49 -0
  270. package/src/harness/__tests__/turn-context.test.ts +178 -0
  271. package/src/harness/__tests__/usage-accumulator.test.ts +83 -0
  272. package/src/harness/capabilities.ts +92 -0
  273. package/src/harness/persist-chokepoint.ts +112 -0
  274. package/src/harness/registry.ts +197 -0
  275. package/src/harness/run-turn.ts +618 -0
  276. package/src/harness/stop-controller.ts +83 -0
  277. package/src/harness/terminal-table.ts +276 -0
  278. package/src/harness/turn-context.ts +1028 -0
  279. package/src/harness/types.ts +473 -0
  280. package/src/harness/usage-accumulator.ts +122 -0
  281. package/src/harness-adapters.ts +30 -0
  282. package/src/main.ts +1 -1
  283. package/src/runner-manager.ts +68 -61
  284. package/src/runner.ts +67 -78
  285. package/src/shared/__tests__/attachment-naming.test.ts +1 -1
  286. package/src/{activities/execute-cursor → shared}/__tests__/attachment-resolver.test.ts +6 -4
  287. package/src/{activities/execute-cursor → shared}/__tests__/cost-guard.test.ts +2 -1
  288. package/src/{activities/execute-cursor → shared}/__tests__/exact-apply.test.ts +3 -3
  289. package/src/{activities/execute-cursor → shared}/__tests__/extract-structured-output.test.ts +8 -8
  290. package/src/{activities/execute-cursor → shared}/__tests__/persist-decision.test.ts +4 -2
  291. package/src/{activities/execute-cursor → shared}/__tests__/skill-resolver.test.ts +1 -1
  292. package/src/shared/__tests__/subagent-rows.test.ts +34 -0
  293. package/src/shared/__tests__/worker-shutdown.test.ts +44 -39
  294. package/src/shared/approval-policy.ts +1 -1
  295. package/src/{activities/execute-cursor → shared}/attachment-resolver.ts +6 -6
  296. package/src/{activities/execute-cursor → shared}/blueprint-resolver.ts +7 -78
  297. package/src/shared/channel-attachment.ts +1 -1
  298. package/src/{activities/execute-cursor → shared}/cost-guard.ts +5 -1
  299. package/src/{activities/execute-cursor → shared}/env-resolver.ts +1 -1
  300. package/src/{activities/execute-cursor → shared}/exact-apply.ts +7 -7
  301. package/src/shared/execution-context.ts +45 -0
  302. package/src/{activities/execute-cursor → shared}/extract-structured-output.ts +10 -7
  303. package/src/shared/filereview/capture.ts +1 -1
  304. package/src/shared/heartbeat.ts +13 -33
  305. package/src/{activities/execute-cursor → shared}/persist-decision.ts +5 -2
  306. package/src/{activities/execute-cursor → shared}/skill-resolver.ts +20 -6
  307. package/src/shared/subagent-rows.ts +39 -0
  308. package/src/shared/worker-shutdown.ts +55 -25
  309. package/src/{activities/execute-cursor/__tests__/workspace-provision.test.ts → shared/workspace/__tests__/session-provision.test.ts} +25 -28
  310. package/src/shared/workspace/platform-dir.ts +1 -1
  311. package/src/{activities/execute-cursor/workspace-provision.ts → shared/workspace/session-provision.ts} +29 -16
  312. package/dist/activities/execute-cursor/attachment-resolver.js.map +0 -1
  313. package/dist/activities/execute-cursor/blueprint-resolver.js.map +0 -1
  314. package/dist/activities/execute-cursor/cost-guard.js.map +0 -1
  315. package/dist/activities/execute-cursor/env-resolver.js.map +0 -1
  316. package/dist/activities/execute-cursor/exact-apply.js.map +0 -1
  317. package/dist/activities/execute-cursor/extract-structured-output.js.map +0 -1
  318. package/dist/activities/execute-cursor/index.d.ts +0 -209
  319. package/dist/activities/execute-cursor/index.js +0 -2345
  320. package/dist/activities/execute-cursor/index.js.map +0 -1
  321. package/dist/activities/execute-cursor/persist-decision.js.map +0 -1
  322. package/dist/activities/execute-cursor/skill-resolver.js.map +0 -1
  323. package/dist/activities/execute-cursor/usage-accumulator.d.ts +0 -89
  324. package/dist/activities/execute-cursor/usage-accumulator.js +0 -121
  325. package/dist/activities/execute-cursor/usage-accumulator.js.map +0 -1
  326. package/dist/activities/execute-cursor/workspace-provision.d.ts +0 -42
  327. package/dist/activities/execute-cursor/workspace-provision.js.map +0 -1
  328. package/src/activities/execute-cursor/__tests__/usage-accumulator.test.ts +0 -164
  329. package/src/activities/execute-cursor/index.ts +0 -2876
  330. package/src/activities/execute-cursor/usage-accumulator.ts +0 -169
  331. /package/dist/{activities/execute-cursor → shared}/env-resolver.js +0 -0
@@ -0,0 +1,342 @@
1
+ /**
2
+ * The Cursor slice of the hermetic activity driver: build the fixture record,
3
+ * the scripted SDK and the `Config`, run the REAL `ExecuteCursor` activity under
4
+ * `MockActivityEnvironment`, and hand back what it persisted.
5
+ *
6
+ * Layering (the `approval-contract/` + `gateway-substrate.ts` split): everything
7
+ * harness-agnostic lives in `src/__test-utils__/hermetic-activity.ts` (the
8
+ * activity environment, the execution record behind the client, the temp
9
+ * `~/.stigmer`, the ticking clock, the shutdown signal). This module adds only
10
+ * what is Cursor's: the `@cursor/sdk` double, the model catalog and pricing
11
+ * registry the harness reads at setup, the Cursor `Config` slice, and the
12
+ * per-scenario reset of the harness's module-level caches.
13
+ *
14
+ * What the two `vi.mock` calls a scenario file must carry look like — they are
15
+ * hoisted by vitest and so cannot live here:
16
+ *
17
+ * ```ts
18
+ * vi.mock("@cursor/sdk", async () =>
19
+ * (await import("../../__test-utils__/scripted-sdk.js")).scriptedCursorSdkModule());
20
+ * vi.mock("../../../../client/stigmer-client.js", async () =>
21
+ * (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule());
22
+ * ```
23
+ *
24
+ * Network: the registry document and the `fetch` stub that serves it are
25
+ * the runtime's fixtures (`src/__test-utils__/model-registry-fixture.ts`);
26
+ * the record's four resources come from `execution-record-fixture.ts` with
27
+ * this harness's ids and model laid over the defaults.
28
+ *
29
+ * The fixture model is `composer-2.5`, pinned (not Auto) on purpose: Auto short-
30
+ * circuits `resolveServiceTierParams` before the catalog, and a pinned model runs
31
+ * the catalog path, the variant-param pinning, and the `run.wait()` model echo
32
+ * check — more of the production path under the golden.
33
+ *
34
+ * Where a scenario reaches the knobs that drive the terminal table, each on
35
+ * the object that models the thing deciding it: the execution's cost budget
36
+ * and the control plane's STOP answer on the record (`CursorRecordOptions`);
37
+ * a control-plane fault on the client (`clientOverrides`); the runner's stall
38
+ * and lock windows on the scenario's `Config` (`config`); an SDK failure on
39
+ * the SDK double (`ScriptedSdkOptions`); an SDK-side cancel or a mid-stream
40
+ * wedge as an `effect` step on the run. Nothing here is a switch in production
41
+ * code — every knob is a value the production path already reads.
42
+ */
43
+
44
+ import { execFileSync } from "node:child_process";
45
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
46
+ import { dirname, join } from "node:path";
47
+ import { create } from "@bufbuild/protobuf";
48
+ import type { ModelListItem } from "@cursor/sdk";
49
+ import {
50
+ LocalPathSourceSchema,
51
+ WorkspaceEntrySchema,
52
+ WorkspaceSourceSchema,
53
+ type WorkspaceEntry,
54
+ } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
55
+ import type { StigmerClient } from "../../../client/stigmer-client.js";
56
+ import type { Config } from "../../../config.js";
57
+ import type { ExecuteActivityInput } from "../../../shared/activity-input.js";
58
+ import {
59
+ ExecutionRecord,
60
+ ScriptedClock,
61
+ bindHermeticClient,
62
+ runActivityHermetically,
63
+ type ActivityInvocation,
64
+ type HermeticEnvironment,
65
+ type InvocationControls,
66
+ } from "../../../__test-utils__/hermetic-activity.js";
67
+ import { executionRecordFixture, type ExecutionRecordOptions } from "../../../__test-utils__/execution-record-fixture.js";
68
+ import { FIXTURE_MODEL } from "../../../__test-utils__/model-registry-fixture.js";
69
+ import { _resetAgentSessionCacheForTests } from "../agent-session-cache.js";
70
+ import { _resetPricingCache } from "../model-pricing-data.js";
71
+ import { resetCatalogCacheForTests } from "../service-tier.js";
72
+ import { _resetRegistryCache } from "../../../shared/model-registry.js";
73
+ import { ScriptedCursorSdk, bindScriptedSdk, type ScriptedSdkOptions } from "./scripted-sdk.js";
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // Fixture ids — fixed so goldens are readable and byte-stable
77
+ // ---------------------------------------------------------------------------
78
+
79
+ export const FIXTURE = {
80
+ org: "hermetic-org",
81
+ executionId: "aex_hermetic_0001",
82
+ sessionId: "ses_hermetic_0001",
83
+ agentInstanceId: "ain_hermetic_0001",
84
+ agentId: "agt_hermetic_0001",
85
+ agentName: "hermetic-agent",
86
+ /** The pinned model; in the registry fixture AND the SDK catalog below. */
87
+ model: FIXTURE_MODEL,
88
+ cursorApiKey: "hermetic-cursor-api-key",
89
+ } as const;
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // The record
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /** The record's knobs; the ids and the default model are this harness's fixture. */
96
+ export type CursorRecordOptions = Omit<ExecutionRecordOptions, "ids">;
97
+
98
+ /** The four resources of one execution, wired by id into a chain, under the Cursor fixture ids. */
99
+ export function cursorExecutionRecord(options: CursorRecordOptions): ExecutionRecord {
100
+ return executionRecordFixture({
101
+ ...options,
102
+ modelName: options.modelName ?? FIXTURE.model,
103
+ ids: {
104
+ org: FIXTURE.org,
105
+ executionId: FIXTURE.executionId,
106
+ sessionId: FIXTURE.sessionId,
107
+ agentInstanceId: FIXTURE.agentInstanceId,
108
+ agentId: FIXTURE.agentId,
109
+ agentName: FIXTURE.agentName,
110
+ },
111
+ });
112
+ }
113
+
114
+ // ---------------------------------------------------------------------------
115
+ // The SDK catalog
116
+ // ---------------------------------------------------------------------------
117
+
118
+ /** The SDK catalog entry for the fixture model: both pinnable params declared. */
119
+ export const SDK_CATALOG: readonly ModelListItem[] = [
120
+ {
121
+ id: FIXTURE.model,
122
+ displayName: "Composer 2.5",
123
+ parameters: [
124
+ { id: "fast", values: [{ value: "true" }, { value: "false" }] },
125
+ { id: "thinking", values: [{ value: "true" }, { value: "false" }] },
126
+ ],
127
+ },
128
+ ];
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // Config
132
+ // ---------------------------------------------------------------------------
133
+
134
+ /** The OSS/local runner posture: direct Cursor API key, no proxy, local mode. */
135
+ export function hermeticCursorConfig(env: HermeticEnvironment): Config {
136
+ return {
137
+ taskQueue: "hermetic-test-queue",
138
+ temporalAddress: "localhost:7233",
139
+ temporalNamespace: "default",
140
+ stigmerBackendEndpoint: "http://localhost:7234",
141
+ mcpBridgeEndpoint: null,
142
+ stigmerToken: null,
143
+ cursorApiKey: FIXTURE.cursorApiKey,
144
+ workspaceRootDir: env.workspaceRootDir,
145
+ mode: "local",
146
+ proxyEndpoint: null,
147
+ maxConcurrentActivities: 1,
148
+ idleTimeoutSeconds: null,
149
+ cloudModeEnabled: false,
150
+ checkpointerType: "memory",
151
+ checkpointerProxyEndpoint: null,
152
+ artifactProxyEndpoint: null,
153
+ primaryModel: FIXTURE.model,
154
+ cursorStreamStallTimeoutMs: 180_000,
155
+ agentResolveTimeoutMs: 120_000,
156
+ workspaceLockTimeoutMs: 900_000,
157
+ };
158
+ }
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // The side effects the real SDK performs, for `effect` steps
162
+ // ---------------------------------------------------------------------------
163
+
164
+ /**
165
+ * The primary workspace directory a session with NO workspace entries runs in
166
+ * (`session-root.ts`: `<workspaceRootDir>/sessions/<sessionId>`).
167
+ */
168
+ export function sessionWorkspaceDir(env: HermeticEnvironment): string {
169
+ return join(env.workspaceRootDir, "sessions", FIXTURE.sessionId);
170
+ }
171
+
172
+ /**
173
+ * Run the workspace's installed preToolUse hook exactly as the Cursor SDK does:
174
+ * read `<workspaceRoot>/.cursor/hooks.json`, take the `preToolUse` command the
175
+ * gate installed (an absolute path to the runner's own stable bash script under
176
+ * `~/.stigmer/hitl-gate/<key>/`), and run it with the hook input on stdin. The
177
+ * script resolves the CURRENT turn's state file and denial ledger from the
178
+ * active-turn pointer, walks its parent PIDs to confirm this process is the
179
+ * runner, and prints `{"permission":"allow"|"deny"}`. A deny appends to the
180
+ * ledger the activity's stream loop reads.
181
+ *
182
+ * This is the out-of-process half of deny-and-retry, driven by the real script
183
+ * against the real gate the activity installed — not a simulation of either.
184
+ */
185
+ export function runWorkspaceHook(
186
+ workspaceRoot: string,
187
+ hookInput: object,
188
+ ): { readonly permission: "allow" | "deny" | "?"; readonly raw: string } {
189
+ const hooksJsonPath = join(workspaceRoot, ".cursor", "hooks.json");
190
+ const parsed = JSON.parse(readFileSync(hooksJsonPath, "utf-8")) as {
191
+ hooks?: { preToolUse?: Array<{ command: string }> };
192
+ };
193
+ const command = parsed.hooks?.preToolUse?.[0]?.command;
194
+ if (!command) {
195
+ throw new Error(`runWorkspaceHook: no preToolUse hook installed in ${hooksJsonPath}`);
196
+ }
197
+ const raw = execFileSync("bash", [command], { input: JSON.stringify(hookInput) }).toString();
198
+ const permission = raw.includes('"permission":"deny"')
199
+ ? "deny"
200
+ : raw.includes('"permission":"allow"')
201
+ ? "allow"
202
+ : "?";
203
+ return { permission, raw };
204
+ }
205
+
206
+ /**
207
+ * A git work tree with one committed file, for the file-review capture
208
+ * scenario. Author, committer and both dates are pinned so the commit AND tree
209
+ * object ids are byte-stable — a file-review golden may carry them.
210
+ */
211
+ export function initGitWorkspace(root: string, files: Record<string, string>): void {
212
+ mkdirSync(root, { recursive: true });
213
+ const gitEnv = {
214
+ ...process.env,
215
+ GIT_AUTHOR_NAME: "hermetic",
216
+ GIT_AUTHOR_EMAIL: "hermetic@stigmer.test",
217
+ GIT_COMMITTER_NAME: "hermetic",
218
+ GIT_COMMITTER_EMAIL: "hermetic@stigmer.test",
219
+ GIT_AUTHOR_DATE: "2026-01-01T00:00:00Z",
220
+ GIT_COMMITTER_DATE: "2026-01-01T00:00:00Z",
221
+ };
222
+ const git = (args: string[]): void => {
223
+ execFileSync("git", args, { cwd: root, env: gitEnv, stdio: "ignore" });
224
+ };
225
+ git(["init", "-q", "-b", "main"]);
226
+ for (const [rel, content] of Object.entries(files)) {
227
+ const abs = join(root, rel);
228
+ mkdirSync(dirname(abs), { recursive: true });
229
+ writeFileSync(abs, content, "utf-8");
230
+ }
231
+ git(["add", "-A"]);
232
+ git(["commit", "-q", "-m", "initial"]);
233
+ }
234
+
235
+ /** A session workspace entry mounting an absolute local path (local mode only). */
236
+ export function localPathEntry(name: string, path: string): WorkspaceEntry {
237
+ return create(WorkspaceEntrySchema, {
238
+ name,
239
+ source: create(WorkspaceSourceSchema, {
240
+ source: { case: "localPath", value: create(LocalPathSourceSchema, { path }) },
241
+ }),
242
+ });
243
+ }
244
+
245
+ // ---------------------------------------------------------------------------
246
+ // Running a scenario
247
+ // ---------------------------------------------------------------------------
248
+
249
+ /**
250
+ * Drop every module-level cache the harness keeps across invocations. Called
251
+ * at the START of a scenario, never between its invocations: a deny-and-retry
252
+ * scenario relies on the parked agent surviving from turn 1 into turn 2 exactly
253
+ * as it does in a live worker.
254
+ */
255
+ export function resetCursorModuleState(): void {
256
+ _resetAgentSessionCacheForTests();
257
+ resetCatalogCacheForTests();
258
+ _resetPricingCache();
259
+ _resetRegistryCache();
260
+ }
261
+
262
+ export interface CursorScenario {
263
+ readonly env: HermeticEnvironment;
264
+ readonly clock: ScriptedClock;
265
+ readonly record: ExecutionRecord;
266
+ readonly sdk: ScriptedCursorSdk;
267
+ /** The runner this scenario runs on: the OSS posture plus the scenario's knobs. */
268
+ readonly config: Config;
269
+ }
270
+
271
+ export interface CursorScenarioOptions {
272
+ readonly env: HermeticEnvironment;
273
+ readonly clock: ScriptedClock;
274
+ readonly record: ExecutionRecord;
275
+ readonly sdk: ScriptedSdkOptions;
276
+ /**
277
+ * Control-plane facets the scenario opts INTO, or faults it injects, over
278
+ * the record's everyday answers (`ExecutionRecord.client`): a rejecting
279
+ * `getAgent` is how a blueprint-resolution failure is staged.
280
+ */
281
+ readonly clientOverrides?: Partial<StigmerClient>;
282
+ /**
283
+ * Runner knobs over {@link hermeticCursorConfig}: a scenario that needs the
284
+ * stall watchdog or the workspace-lock wait to expire states the window
285
+ * here. A property of the runner the scenario runs on, not of one turn, so
286
+ * it lives on the scenario and every turn of it sees the same `Config`.
287
+ */
288
+ readonly config?: Partial<Config>;
289
+ }
290
+
291
+ /** Bind the record and the SDK for a scenario; resets the harness caches first. */
292
+ export function beginCursorScenario(options: CursorScenarioOptions): CursorScenario {
293
+ resetCursorModuleState();
294
+ const sdk = new ScriptedCursorSdk(options.sdk);
295
+ bindScriptedSdk(sdk);
296
+ bindHermeticClient(options.record.client(options.clientOverrides));
297
+ return {
298
+ env: options.env,
299
+ clock: options.clock,
300
+ record: options.record,
301
+ sdk,
302
+ config: { ...hermeticCursorConfig(options.env), ...options.config },
303
+ };
304
+ }
305
+
306
+ export interface CursorTurnOptions {
307
+ /** Empty for a first invocation; the agent id for a HITL reinvocation. */
308
+ readonly threadId?: string;
309
+ /** The HITL cycle index (0 on the first turn); mints the change-set id. */
310
+ readonly turnSeq?: number;
311
+ readonly onControls?: (controls: InvocationControls) => void;
312
+ }
313
+
314
+ /**
315
+ * Run ONE `ExecuteCursor` invocation for the scenario: the real Cursor
316
+ * adapter under the real turn runtime, as the composition roots wire them.
317
+ * Built per invocation (the registry constructs its client, which is the one
318
+ * bound at `beginCursorScenario`; the adapter boots on the scenario's config).
319
+ */
320
+ export async function runCursorTurn(
321
+ scenario: CursorScenario,
322
+ options: CursorTurnOptions = {},
323
+ ): Promise<ActivityInvocation> {
324
+ // Imported lazily so the scenario file's `vi.mock` declarations are in
325
+ // force before the adapter module is loaded and before its `boot` loads
326
+ // `@cursor/sdk` (through `turn.ts`) and the registry loads the client.
327
+ const { createCursorAdapter } = await import("../adapter.js");
328
+ const { createHarnessActivities } = await import("../../../harness/registry.js");
329
+ const adapter = createCursorAdapter();
330
+ await adapter.boot(scenario.config);
331
+ const activities = await createHarnessActivities([{ harness: "cursor", adapter }], scenario.config);
332
+ // The typed wire shape the control plane's workflow sends (activity-input.ts).
333
+ const input: ExecuteActivityInput = {
334
+ execution_id: scenario.record.executionId,
335
+ thread_id: options.threadId ?? "",
336
+ turn_seq: options.turnSeq ?? 0,
337
+ };
338
+ return runActivityHermetically(activities.ExecuteCursor!, [input], {
339
+ taskQueue: "hermetic-test-queue",
340
+ onControls: options.onControls,
341
+ });
342
+ }