@stigmer/runner 3.0.1

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 (904) hide show
  1. package/README.md +212 -0
  2. package/dist/.build-fingerprint +1 -0
  3. package/dist/activities/call-agent-status.d.ts +37 -0
  4. package/dist/activities/call-agent-status.js +91 -0
  5. package/dist/activities/call-agent-status.js.map +1 -0
  6. package/dist/activities/call-agent.d.ts +25 -0
  7. package/dist/activities/call-agent.js +233 -0
  8. package/dist/activities/call-agent.js.map +1 -0
  9. package/dist/activities/call-eval.d.ts +50 -0
  10. package/dist/activities/call-eval.js +244 -0
  11. package/dist/activities/call-eval.js.map +1 -0
  12. package/dist/activities/call-function.d.ts +21 -0
  13. package/dist/activities/call-function.js +54 -0
  14. package/dist/activities/call-function.js.map +1 -0
  15. package/dist/activities/call-grpc.d.ts +22 -0
  16. package/dist/activities/call-grpc.js +101 -0
  17. package/dist/activities/call-grpc.js.map +1 -0
  18. package/dist/activities/call-http.d.ts +32 -0
  19. package/dist/activities/call-http.js +134 -0
  20. package/dist/activities/call-http.js.map +1 -0
  21. package/dist/activities/call-llm.d.ts +39 -0
  22. package/dist/activities/call-llm.js +260 -0
  23. package/dist/activities/call-llm.js.map +1 -0
  24. package/dist/activities/call-transform.d.ts +20 -0
  25. package/dist/activities/call-transform.js +33 -0
  26. package/dist/activities/call-transform.js.map +1 -0
  27. package/dist/activities/call-validate.d.ts +41 -0
  28. package/dist/activities/call-validate.js +163 -0
  29. package/dist/activities/call-validate.js.map +1 -0
  30. package/dist/activities/classify-tool-approvals.d.ts +47 -0
  31. package/dist/activities/classify-tool-approvals.js +207 -0
  32. package/dist/activities/classify-tool-approvals.js.map +1 -0
  33. package/dist/activities/discover-mcp-server.d.ts +65 -0
  34. package/dist/activities/discover-mcp-server.js +269 -0
  35. package/dist/activities/discover-mcp-server.js.map +1 -0
  36. package/dist/activities/emit-event.d.ts +46 -0
  37. package/dist/activities/emit-event.js +125 -0
  38. package/dist/activities/emit-event.js.map +1 -0
  39. package/dist/activities/ensure-thread.d.ts +24 -0
  40. package/dist/activities/ensure-thread.js +44 -0
  41. package/dist/activities/ensure-thread.js.map +1 -0
  42. package/dist/activities/evaluate-expressions.d.ts +21 -0
  43. package/dist/activities/evaluate-expressions.js +39 -0
  44. package/dist/activities/evaluate-expressions.js.map +1 -0
  45. package/dist/activities/execute-cursor/approval-policy.d.ts +104 -0
  46. package/dist/activities/execute-cursor/approval-policy.js +193 -0
  47. package/dist/activities/execute-cursor/approval-policy.js.map +1 -0
  48. package/dist/activities/execute-cursor/approval-state.d.ts +157 -0
  49. package/dist/activities/execute-cursor/approval-state.js +223 -0
  50. package/dist/activities/execute-cursor/approval-state.js.map +1 -0
  51. package/dist/activities/execute-cursor/attachment-resolver.d.ts +19 -0
  52. package/dist/activities/execute-cursor/attachment-resolver.js +52 -0
  53. package/dist/activities/execute-cursor/attachment-resolver.js.map +1 -0
  54. package/dist/activities/execute-cursor/blueprint-resolver.d.ts +66 -0
  55. package/dist/activities/execute-cursor/blueprint-resolver.js +169 -0
  56. package/dist/activities/execute-cursor/blueprint-resolver.js.map +1 -0
  57. package/dist/activities/execute-cursor/connect-backfill.d.ts +18 -0
  58. package/dist/activities/execute-cursor/connect-backfill.js +27 -0
  59. package/dist/activities/execute-cursor/connect-backfill.js.map +1 -0
  60. package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +24 -0
  61. package/dist/activities/execute-cursor/cursor-event-recorder.js +66 -0
  62. package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -0
  63. package/dist/activities/execute-cursor/cursor-mode.d.ts +32 -0
  64. package/dist/activities/execute-cursor/cursor-mode.js +36 -0
  65. package/dist/activities/execute-cursor/cursor-mode.js.map +1 -0
  66. package/dist/activities/execute-cursor/delta-enricher.d.ts +87 -0
  67. package/dist/activities/execute-cursor/delta-enricher.js +265 -0
  68. package/dist/activities/execute-cursor/delta-enricher.js.map +1 -0
  69. package/dist/activities/execute-cursor/env-resolver.d.ts +19 -0
  70. package/dist/activities/execute-cursor/env-resolver.js +47 -0
  71. package/dist/activities/execute-cursor/env-resolver.js.map +1 -0
  72. package/dist/activities/execute-cursor/error-classifier.d.ts +73 -0
  73. package/dist/activities/execute-cursor/error-classifier.js +185 -0
  74. package/dist/activities/execute-cursor/error-classifier.js.map +1 -0
  75. package/dist/activities/execute-cursor/fetch-interceptor.d.ts +59 -0
  76. package/dist/activities/execute-cursor/fetch-interceptor.js +317 -0
  77. package/dist/activities/execute-cursor/fetch-interceptor.js.map +1 -0
  78. package/dist/activities/execute-cursor/hitl-diagnostics.d.ts +32 -0
  79. package/dist/activities/execute-cursor/hitl-diagnostics.js +73 -0
  80. package/dist/activities/execute-cursor/hitl-diagnostics.js.map +1 -0
  81. package/dist/activities/execute-cursor/hook-script.d.ts +47 -0
  82. package/dist/activities/execute-cursor/hook-script.js +156 -0
  83. package/dist/activities/execute-cursor/hook-script.js.map +1 -0
  84. package/dist/activities/execute-cursor/http2-interceptor.d.ts +94 -0
  85. package/dist/activities/execute-cursor/http2-interceptor.js +209 -0
  86. package/dist/activities/execute-cursor/http2-interceptor.js.map +1 -0
  87. package/dist/activities/execute-cursor/index.d.ts +67 -0
  88. package/dist/activities/execute-cursor/index.js +1176 -0
  89. package/dist/activities/execute-cursor/index.js.map +1 -0
  90. package/dist/activities/execute-cursor/mcp-config.d.ts +30 -0
  91. package/dist/activities/execute-cursor/mcp-config.js +39 -0
  92. package/dist/activities/execute-cursor/mcp-config.js.map +1 -0
  93. package/dist/activities/execute-cursor/mcp-resolver.d.ts +91 -0
  94. package/dist/activities/execute-cursor/mcp-resolver.js +178 -0
  95. package/dist/activities/execute-cursor/mcp-resolver.js.map +1 -0
  96. package/dist/activities/execute-cursor/message-translator.d.ts +211 -0
  97. package/dist/activities/execute-cursor/message-translator.js +786 -0
  98. package/dist/activities/execute-cursor/message-translator.js.map +1 -0
  99. package/dist/activities/execute-cursor/model-pricing-data.d.ts +40 -0
  100. package/dist/activities/execute-cursor/model-pricing-data.js +114 -0
  101. package/dist/activities/execute-cursor/model-pricing-data.js.map +1 -0
  102. package/dist/activities/execute-cursor/model-pricing.d.ts +42 -0
  103. package/dist/activities/execute-cursor/model-pricing.js +141 -0
  104. package/dist/activities/execute-cursor/model-pricing.js.map +1 -0
  105. package/dist/activities/execute-cursor/placeholder-resolver.d.ts +34 -0
  106. package/dist/activities/execute-cursor/placeholder-resolver.js +82 -0
  107. package/dist/activities/execute-cursor/placeholder-resolver.js.map +1 -0
  108. package/dist/activities/execute-cursor/prompt-builder.d.ts +80 -0
  109. package/dist/activities/execute-cursor/prompt-builder.js +280 -0
  110. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -0
  111. package/dist/activities/execute-cursor/rejection-capture.d.ts +30 -0
  112. package/dist/activities/execute-cursor/rejection-capture.js +80 -0
  113. package/dist/activities/execute-cursor/rejection-capture.js.map +1 -0
  114. package/dist/activities/execute-cursor/session-lifecycle.d.ts +189 -0
  115. package/dist/activities/execute-cursor/session-lifecycle.js +285 -0
  116. package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -0
  117. package/dist/activities/execute-cursor/skill-resolver.d.ts +29 -0
  118. package/dist/activities/execute-cursor/skill-resolver.js +134 -0
  119. package/dist/activities/execute-cursor/skill-resolver.js.map +1 -0
  120. package/dist/activities/execute-cursor/subagent-config.d.ts +34 -0
  121. package/dist/activities/execute-cursor/subagent-config.js +55 -0
  122. package/dist/activities/execute-cursor/subagent-config.js.map +1 -0
  123. package/dist/activities/execute-cursor/todo-tracker.d.ts +35 -0
  124. package/dist/activities/execute-cursor/todo-tracker.js +108 -0
  125. package/dist/activities/execute-cursor/todo-tracker.js.map +1 -0
  126. package/dist/activities/execute-cursor/usage-accumulator.d.ts +55 -0
  127. package/dist/activities/execute-cursor/usage-accumulator.js +89 -0
  128. package/dist/activities/execute-cursor/usage-accumulator.js.map +1 -0
  129. package/dist/activities/execute-cursor/workspace-provision.d.ts +22 -0
  130. package/dist/activities/execute-cursor/workspace-provision.js +37 -0
  131. package/dist/activities/execute-cursor/workspace-provision.js.map +1 -0
  132. package/dist/activities/execute-cursor/workspace-setup.d.ts +27 -0
  133. package/dist/activities/execute-cursor/workspace-setup.js +61 -0
  134. package/dist/activities/execute-cursor/workspace-setup.js.map +1 -0
  135. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +71 -0
  136. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +182 -0
  137. package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -0
  138. package/dist/activities/execute-deep-agent/attachment-injector.d.ts +67 -0
  139. package/dist/activities/execute-deep-agent/attachment-injector.js +306 -0
  140. package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -0
  141. package/dist/activities/execute-deep-agent/auto-publish.d.ts +17 -0
  142. package/dist/activities/execute-deep-agent/auto-publish.js +71 -0
  143. package/dist/activities/execute-deep-agent/auto-publish.js.map +1 -0
  144. package/dist/activities/execute-deep-agent/environment.d.ts +24 -0
  145. package/dist/activities/execute-deep-agent/environment.js +50 -0
  146. package/dist/activities/execute-deep-agent/environment.js.map +1 -0
  147. package/dist/activities/execute-deep-agent/event-recorder.d.ts +21 -0
  148. package/dist/activities/execute-deep-agent/event-recorder.js +67 -0
  149. package/dist/activities/execute-deep-agent/event-recorder.js.map +1 -0
  150. package/dist/activities/execute-deep-agent/execution-state.d.ts +61 -0
  151. package/dist/activities/execute-deep-agent/execution-state.js +76 -0
  152. package/dist/activities/execute-deep-agent/execution-state.js.map +1 -0
  153. package/dist/activities/execute-deep-agent/execution-status-writer.d.ts +17 -0
  154. package/dist/activities/execute-deep-agent/execution-status-writer.js +9 -0
  155. package/dist/activities/execute-deep-agent/execution-status-writer.js.map +1 -0
  156. package/dist/activities/execute-deep-agent/hitl.d.ts +58 -0
  157. package/dist/activities/execute-deep-agent/hitl.js +155 -0
  158. package/dist/activities/execute-deep-agent/hitl.js.map +1 -0
  159. package/dist/activities/execute-deep-agent/index.d.ts +14 -0
  160. package/dist/activities/execute-deep-agent/index.js +286 -0
  161. package/dist/activities/execute-deep-agent/index.js.map +1 -0
  162. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +36 -0
  163. package/dist/activities/execute-deep-agent/inline-publisher.js +105 -0
  164. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -0
  165. package/dist/activities/execute-deep-agent/post-stream.d.ts +23 -0
  166. package/dist/activities/execute-deep-agent/post-stream.js +71 -0
  167. package/dist/activities/execute-deep-agent/post-stream.js.map +1 -0
  168. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +27 -0
  169. package/dist/activities/execute-deep-agent/prompt-builder.js +200 -0
  170. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -0
  171. package/dist/activities/execute-deep-agent/setup.d.ts +55 -0
  172. package/dist/activities/execute-deep-agent/setup.js +411 -0
  173. package/dist/activities/execute-deep-agent/setup.js.map +1 -0
  174. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +39 -0
  175. package/dist/activities/execute-deep-agent/status-builder-shared.js +120 -0
  176. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -0
  177. package/dist/activities/execute-deep-agent/status-builder.d.ts +81 -0
  178. package/dist/activities/execute-deep-agent/status-builder.js +312 -0
  179. package/dist/activities/execute-deep-agent/status-builder.js.map +1 -0
  180. package/dist/activities/execute-deep-agent/streaming-scheduler.d.ts +60 -0
  181. package/dist/activities/execute-deep-agent/streaming-scheduler.js +114 -0
  182. package/dist/activities/execute-deep-agent/streaming-scheduler.js.map +1 -0
  183. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +22 -0
  184. package/dist/activities/execute-deep-agent/streaming-side-effects.js +83 -0
  185. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -0
  186. package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +12 -0
  187. package/dist/activities/execute-deep-agent/streaming-terminal.js +71 -0
  188. package/dist/activities/execute-deep-agent/streaming-terminal.js.map +1 -0
  189. package/dist/activities/execute-deep-agent/streaming-v3.d.ts +13 -0
  190. package/dist/activities/execute-deep-agent/streaming-v3.js +170 -0
  191. package/dist/activities/execute-deep-agent/streaming-v3.js.map +1 -0
  192. package/dist/activities/execute-deep-agent/streaming.d.ts +66 -0
  193. package/dist/activities/execute-deep-agent/streaming.js +169 -0
  194. package/dist/activities/execute-deep-agent/streaming.js.map +1 -0
  195. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +90 -0
  196. package/dist/activities/execute-deep-agent/subagent-tracker.js +364 -0
  197. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -0
  198. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +150 -0
  199. package/dist/activities/execute-deep-agent/subagent-transformer.js +450 -0
  200. package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -0
  201. package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +28 -0
  202. package/dist/activities/execute-deep-agent/subagent-wiring.js +40 -0
  203. package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -0
  204. package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +31 -0
  205. package/dist/activities/execute-deep-agent/v3-event-recorder.js +71 -0
  206. package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -0
  207. package/dist/activities/execute-deep-agent/v3-events.d.ts +102 -0
  208. package/dist/activities/execute-deep-agent/v3-events.js +35 -0
  209. package/dist/activities/execute-deep-agent/v3-events.js.map +1 -0
  210. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +15 -0
  211. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +235 -0
  212. package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +1 -0
  213. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +68 -0
  214. package/dist/activities/execute-deep-agent/v3-status-builder.js +394 -0
  215. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -0
  216. package/dist/activities/execute-deep-agent/writeback-coordinator.d.ts +71 -0
  217. package/dist/activities/execute-deep-agent/writeback-coordinator.js +295 -0
  218. package/dist/activities/execute-deep-agent/writeback-coordinator.js.map +1 -0
  219. package/dist/activities/hydrate-workflow-execution.d.ts +32 -0
  220. package/dist/activities/hydrate-workflow-execution.js +212 -0
  221. package/dist/activities/hydrate-workflow-execution.js.map +1 -0
  222. package/dist/activities/notification.d.ts +19 -0
  223. package/dist/activities/notification.js +47 -0
  224. package/dist/activities/notification.js.map +1 -0
  225. package/dist/activities/promote-task-output.d.ts +38 -0
  226. package/dist/activities/promote-task-output.js +90 -0
  227. package/dist/activities/promote-task-output.js.map +1 -0
  228. package/dist/activities/run-command.d.ts +15 -0
  229. package/dist/activities/run-command.js +123 -0
  230. package/dist/activities/run-command.js.map +1 -0
  231. package/dist/activities/workflow-event-activities.d.ts +48 -0
  232. package/dist/activities/workflow-event-activities.js +415 -0
  233. package/dist/activities/workflow-event-activities.js.map +1 -0
  234. package/dist/bootstrap.d.ts +80 -0
  235. package/dist/bootstrap.js +114 -0
  236. package/dist/bootstrap.js.map +1 -0
  237. package/dist/budget/index.d.ts +1 -0
  238. package/dist/budget/index.js +2 -0
  239. package/dist/budget/index.js.map +1 -0
  240. package/dist/budget/tracker.d.ts +52 -0
  241. package/dist/budget/tracker.js +123 -0
  242. package/dist/budget/tracker.js.map +1 -0
  243. package/dist/claimcheck/compressor.d.ts +2 -0
  244. package/dist/claimcheck/compressor.js +8 -0
  245. package/dist/claimcheck/compressor.js.map +1 -0
  246. package/dist/claimcheck/config.d.ts +7 -0
  247. package/dist/claimcheck/config.js +10 -0
  248. package/dist/claimcheck/config.js.map +1 -0
  249. package/dist/claimcheck/index.d.ts +3 -0
  250. package/dist/claimcheck/index.js +4 -0
  251. package/dist/claimcheck/index.js.map +1 -0
  252. package/dist/claimcheck/payload-codec.d.ts +23 -0
  253. package/dist/claimcheck/payload-codec.js +81 -0
  254. package/dist/claimcheck/payload-codec.js.map +1 -0
  255. package/dist/client/server-contracts.d.ts +52 -0
  256. package/dist/client/server-contracts.js +72 -0
  257. package/dist/client/server-contracts.js.map +1 -0
  258. package/dist/client/stigmer-client.d.ts +131 -0
  259. package/dist/client/stigmer-client.js +239 -0
  260. package/dist/client/stigmer-client.js.map +1 -0
  261. package/dist/config.d.ts +64 -0
  262. package/dist/config.js +123 -0
  263. package/dist/config.js.map +1 -0
  264. package/dist/idle-watchdog.d.ts +11 -0
  265. package/dist/idle-watchdog.js +24 -0
  266. package/dist/idle-watchdog.js.map +1 -0
  267. package/dist/index.d.ts +43 -0
  268. package/dist/index.js +42 -0
  269. package/dist/index.js.map +1 -0
  270. package/dist/interceptors/workflow-metrics-sink.d.ts +11 -0
  271. package/dist/interceptors/workflow-metrics-sink.js +51 -0
  272. package/dist/interceptors/workflow-metrics-sink.js.map +1 -0
  273. package/dist/ipc-protocol-fixtures.d.ts +32 -0
  274. package/dist/ipc-protocol-fixtures.js +69 -0
  275. package/dist/ipc-protocol-fixtures.js.map +1 -0
  276. package/dist/ipc-protocol.d.ts +60 -0
  277. package/dist/ipc-protocol.js +19 -0
  278. package/dist/ipc-protocol.js.map +1 -0
  279. package/dist/main.d.ts +19 -0
  280. package/dist/main.js +292 -0
  281. package/dist/main.js.map +1 -0
  282. package/dist/middleware/approval-gate.d.ts +30 -0
  283. package/dist/middleware/approval-gate.js +125 -0
  284. package/dist/middleware/approval-gate.js.map +1 -0
  285. package/dist/middleware/cost-cap.d.ts +22 -0
  286. package/dist/middleware/cost-cap.js +159 -0
  287. package/dist/middleware/cost-cap.js.map +1 -0
  288. package/dist/middleware/error-hints.d.ts +27 -0
  289. package/dist/middleware/error-hints.js +116 -0
  290. package/dist/middleware/error-hints.js.map +1 -0
  291. package/dist/middleware/execution-budget.d.ts +20 -0
  292. package/dist/middleware/execution-budget.js +151 -0
  293. package/dist/middleware/execution-budget.js.map +1 -0
  294. package/dist/middleware/graceful-stop.d.ts +17 -0
  295. package/dist/middleware/graceful-stop.js +63 -0
  296. package/dist/middleware/graceful-stop.js.map +1 -0
  297. package/dist/middleware/index.d.ts +27 -0
  298. package/dist/middleware/index.js +45 -0
  299. package/dist/middleware/index.js.map +1 -0
  300. package/dist/middleware/loop-detection.d.ts +14 -0
  301. package/dist/middleware/loop-detection.js +156 -0
  302. package/dist/middleware/loop-detection.js.map +1 -0
  303. package/dist/middleware/otel-spans.d.ts +11 -0
  304. package/dist/middleware/otel-spans.js +177 -0
  305. package/dist/middleware/otel-spans.js.map +1 -0
  306. package/dist/middleware/think-tool.d.ts +23 -0
  307. package/dist/middleware/think-tool.js +33 -0
  308. package/dist/middleware/think-tool.js.map +1 -0
  309. package/dist/middleware/tool-truncation.d.ts +16 -0
  310. package/dist/middleware/tool-truncation.js +67 -0
  311. package/dist/middleware/tool-truncation.js.map +1 -0
  312. package/dist/middleware/types.d.ts +100 -0
  313. package/dist/middleware/types.js +9 -0
  314. package/dist/middleware/types.js.map +1 -0
  315. package/dist/notification/index.d.ts +2 -0
  316. package/dist/notification/index.js +6 -0
  317. package/dist/notification/index.js.map +1 -0
  318. package/dist/notification/provider.d.ts +29 -0
  319. package/dist/notification/provider.js +25 -0
  320. package/dist/notification/provider.js.map +1 -0
  321. package/dist/notification/webhook.d.ts +13 -0
  322. package/dist/notification/webhook.js +55 -0
  323. package/dist/notification/webhook.js.map +1 -0
  324. package/dist/otel-metrics.d.ts +21 -0
  325. package/dist/otel-metrics.js +54 -0
  326. package/dist/otel-metrics.js.map +1 -0
  327. package/dist/otel.d.ts +57 -0
  328. package/dist/otel.js +164 -0
  329. package/dist/otel.js.map +1 -0
  330. package/dist/runner-manager.d.ts +113 -0
  331. package/dist/runner-manager.js +412 -0
  332. package/dist/runner-manager.js.map +1 -0
  333. package/dist/runner-token-coordinator.d.ts +56 -0
  334. package/dist/runner-token-coordinator.js +84 -0
  335. package/dist/runner-token-coordinator.js.map +1 -0
  336. package/dist/runner.d.ts +104 -0
  337. package/dist/runner.js +234 -0
  338. package/dist/runner.js.map +1 -0
  339. package/dist/shared/approval-policy.d.ts +45 -0
  340. package/dist/shared/approval-policy.js +122 -0
  341. package/dist/shared/approval-policy.js.map +1 -0
  342. package/dist/shared/artifact-storage.d.ts +44 -0
  343. package/dist/shared/artifact-storage.js +162 -0
  344. package/dist/shared/artifact-storage.js.map +1 -0
  345. package/dist/shared/checkpointer/factory.d.ts +28 -0
  346. package/dist/shared/checkpointer/factory.js +55 -0
  347. package/dist/shared/checkpointer/factory.js.map +1 -0
  348. package/dist/shared/checkpointer/http-saver.d.ts +34 -0
  349. package/dist/shared/checkpointer/http-saver.js +274 -0
  350. package/dist/shared/checkpointer/http-saver.js.map +1 -0
  351. package/dist/shared/checkpointer/types.d.ts +12 -0
  352. package/dist/shared/checkpointer/types.js +2 -0
  353. package/dist/shared/checkpointer/types.js.map +1 -0
  354. package/dist/shared/connect-backfill.d.ts +58 -0
  355. package/dist/shared/connect-backfill.js +119 -0
  356. package/dist/shared/connect-backfill.js.map +1 -0
  357. package/dist/shared/extract-json.d.ts +26 -0
  358. package/dist/shared/extract-json.js +140 -0
  359. package/dist/shared/extract-json.js.map +1 -0
  360. package/dist/shared/grpc-retry.d.ts +35 -0
  361. package/dist/shared/grpc-retry.js +78 -0
  362. package/dist/shared/grpc-retry.js.map +1 -0
  363. package/dist/shared/heartbeat.d.ts +22 -0
  364. package/dist/shared/heartbeat.js +55 -0
  365. package/dist/shared/heartbeat.js.map +1 -0
  366. package/dist/shared/json-schema-to-zod.d.ts +13 -0
  367. package/dist/shared/json-schema-to-zod.js +49 -0
  368. package/dist/shared/json-schema-to-zod.js.map +1 -0
  369. package/dist/shared/llm-proxy.d.ts +57 -0
  370. package/dist/shared/llm-proxy.js +116 -0
  371. package/dist/shared/llm-proxy.js.map +1 -0
  372. package/dist/shared/mcp-manager.d.ts +47 -0
  373. package/dist/shared/mcp-manager.js +118 -0
  374. package/dist/shared/mcp-manager.js.map +1 -0
  375. package/dist/shared/mcp-resolver.d.ts +41 -0
  376. package/dist/shared/mcp-resolver.js +96 -0
  377. package/dist/shared/mcp-resolver.js.map +1 -0
  378. package/dist/shared/model-pricing-data.d.ts +18 -0
  379. package/dist/shared/model-pricing-data.js +78 -0
  380. package/dist/shared/model-pricing-data.js.map +1 -0
  381. package/dist/shared/model-pricing.d.ts +24 -0
  382. package/dist/shared/model-pricing.js +58 -0
  383. package/dist/shared/model-pricing.js.map +1 -0
  384. package/dist/shared/model-registry.d.ts +55 -0
  385. package/dist/shared/model-registry.js +178 -0
  386. package/dist/shared/model-registry.js.map +1 -0
  387. package/dist/shared/placeholder-resolver.d.ts +27 -0
  388. package/dist/shared/placeholder-resolver.js +75 -0
  389. package/dist/shared/placeholder-resolver.js.map +1 -0
  390. package/dist/shared/plan-artifact.d.ts +56 -0
  391. package/dist/shared/plan-artifact.js +98 -0
  392. package/dist/shared/plan-artifact.js.map +1 -0
  393. package/dist/shared/skill-relevance.d.ts +65 -0
  394. package/dist/shared/skill-relevance.js +175 -0
  395. package/dist/shared/skill-relevance.js.map +1 -0
  396. package/dist/shared/skill-writer.d.ts +73 -0
  397. package/dist/shared/skill-writer.js +230 -0
  398. package/dist/shared/skill-writer.js.map +1 -0
  399. package/dist/shared/status.d.ts +37 -0
  400. package/dist/shared/status.js +73 -0
  401. package/dist/shared/status.js.map +1 -0
  402. package/dist/shared/subagent-gate.d.ts +41 -0
  403. package/dist/shared/subagent-gate.js +93 -0
  404. package/dist/shared/subagent-gate.js.map +1 -0
  405. package/dist/shared/tool-kind.d.ts +22 -0
  406. package/dist/shared/tool-kind.js +79 -0
  407. package/dist/shared/tool-kind.js.map +1 -0
  408. package/dist/shared/workspace/file-tree.d.ts +13 -0
  409. package/dist/shared/workspace/file-tree.js +101 -0
  410. package/dist/shared/workspace/file-tree.js.map +1 -0
  411. package/dist/shared/workspace/local-backend.d.ts +41 -0
  412. package/dist/shared/workspace/local-backend.js +113 -0
  413. package/dist/shared/workspace/local-backend.js.map +1 -0
  414. package/dist/shared/workspace/platform-dir.d.ts +25 -0
  415. package/dist/shared/workspace/platform-dir.js +36 -0
  416. package/dist/shared/workspace/platform-dir.js.map +1 -0
  417. package/dist/shared/workspace/platform-mount.d.ts +95 -0
  418. package/dist/shared/workspace/platform-mount.js +157 -0
  419. package/dist/shared/workspace/platform-mount.js.map +1 -0
  420. package/dist/shared/workspace/provisioner.d.ts +47 -0
  421. package/dist/shared/workspace/provisioner.js +84 -0
  422. package/dist/shared/workspace/provisioner.js.map +1 -0
  423. package/dist/shared/workspace/sources/empty.d.ts +8 -0
  424. package/dist/shared/workspace/sources/empty.js +18 -0
  425. package/dist/shared/workspace/sources/empty.js.map +1 -0
  426. package/dist/shared/workspace/sources/git.d.ts +22 -0
  427. package/dist/shared/workspace/sources/git.js +207 -0
  428. package/dist/shared/workspace/sources/git.js.map +1 -0
  429. package/dist/shared/workspace/sources/local-path.d.ts +17 -0
  430. package/dist/shared/workspace/sources/local-path.js +57 -0
  431. package/dist/shared/workspace/sources/local-path.js.map +1 -0
  432. package/dist/shared/workspace/types.d.ts +58 -0
  433. package/dist/shared/workspace/types.js +25 -0
  434. package/dist/shared/workspace/types.js.map +1 -0
  435. package/dist/shared/zip-extract.d.ts +30 -0
  436. package/dist/shared/zip-extract.js +150 -0
  437. package/dist/shared/zip-extract.js.map +1 -0
  438. package/dist/worker.d.ts +27 -0
  439. package/dist/worker.js +65 -0
  440. package/dist/worker.js.map +1 -0
  441. package/dist/workflow-engine/clone.d.ts +11 -0
  442. package/dist/workflow-engine/clone.js +21 -0
  443. package/dist/workflow-engine/clone.js.map +1 -0
  444. package/dist/workflow-engine/do-executor.d.ts +27 -0
  445. package/dist/workflow-engine/do-executor.js +418 -0
  446. package/dist/workflow-engine/do-executor.js.map +1 -0
  447. package/dist/workflow-engine/duration.d.ts +12 -0
  448. package/dist/workflow-engine/duration.js +25 -0
  449. package/dist/workflow-engine/duration.js.map +1 -0
  450. package/dist/workflow-engine/error-utils.d.ts +42 -0
  451. package/dist/workflow-engine/error-utils.js +77 -0
  452. package/dist/workflow-engine/error-utils.js.map +1 -0
  453. package/dist/workflow-engine/errors.d.ts +46 -0
  454. package/dist/workflow-engine/errors.js +105 -0
  455. package/dist/workflow-engine/errors.js.map +1 -0
  456. package/dist/workflow-engine/expression-utils.d.ts +60 -0
  457. package/dist/workflow-engine/expression-utils.js +108 -0
  458. package/dist/workflow-engine/expression-utils.js.map +1 -0
  459. package/dist/workflow-engine/expression.d.ts +132 -0
  460. package/dist/workflow-engine/expression.js +366 -0
  461. package/dist/workflow-engine/expression.js.map +1 -0
  462. package/dist/workflow-engine/loader.d.ts +23 -0
  463. package/dist/workflow-engine/loader.js +429 -0
  464. package/dist/workflow-engine/loader.js.map +1 -0
  465. package/dist/workflow-engine/recovery.d.ts +53 -0
  466. package/dist/workflow-engine/recovery.js +46 -0
  467. package/dist/workflow-engine/recovery.js.map +1 -0
  468. package/dist/workflow-engine/resolve.d.ts +83 -0
  469. package/dist/workflow-engine/resolve.js +257 -0
  470. package/dist/workflow-engine/resolve.js.map +1 -0
  471. package/dist/workflow-engine/retry.d.ts +30 -0
  472. package/dist/workflow-engine/retry.js +97 -0
  473. package/dist/workflow-engine/retry.js.map +1 -0
  474. package/dist/workflow-engine/state.d.ts +26 -0
  475. package/dist/workflow-engine/state.js +49 -0
  476. package/dist/workflow-engine/state.js.map +1 -0
  477. package/dist/workflow-engine/task-factory.d.ts +20 -0
  478. package/dist/workflow-engine/task-factory.js +133 -0
  479. package/dist/workflow-engine/task-factory.js.map +1 -0
  480. package/dist/workflow-engine/task-status-accumulator.d.ts +59 -0
  481. package/dist/workflow-engine/task-status-accumulator.js +164 -0
  482. package/dist/workflow-engine/task-status-accumulator.js.map +1 -0
  483. package/dist/workflow-engine/tasks/call-agent-output.d.ts +26 -0
  484. package/dist/workflow-engine/tasks/call-agent-output.js +109 -0
  485. package/dist/workflow-engine/tasks/call-agent-output.js.map +1 -0
  486. package/dist/workflow-engine/tasks/call-agent.d.ts +31 -0
  487. package/dist/workflow-engine/tasks/call-agent.js +161 -0
  488. package/dist/workflow-engine/tasks/call-agent.js.map +1 -0
  489. package/dist/workflow-engine/tasks/call-function.d.ts +19 -0
  490. package/dist/workflow-engine/tasks/call-function.js +64 -0
  491. package/dist/workflow-engine/tasks/call-function.js.map +1 -0
  492. package/dist/workflow-engine/tasks/call-grpc.d.ts +15 -0
  493. package/dist/workflow-engine/tasks/call-grpc.js +27 -0
  494. package/dist/workflow-engine/tasks/call-grpc.js.map +1 -0
  495. package/dist/workflow-engine/tasks/call-http.d.ts +19 -0
  496. package/dist/workflow-engine/tasks/call-http.js +31 -0
  497. package/dist/workflow-engine/tasks/call-http.js.map +1 -0
  498. package/dist/workflow-engine/tasks/for.d.ts +39 -0
  499. package/dist/workflow-engine/tasks/for.js +154 -0
  500. package/dist/workflow-engine/tasks/for.js.map +1 -0
  501. package/dist/workflow-engine/tasks/fork.d.ts +42 -0
  502. package/dist/workflow-engine/tasks/fork.js +142 -0
  503. package/dist/workflow-engine/tasks/fork.js.map +1 -0
  504. package/dist/workflow-engine/tasks/human-input.d.ts +33 -0
  505. package/dist/workflow-engine/tasks/human-input.js +109 -0
  506. package/dist/workflow-engine/tasks/human-input.js.map +1 -0
  507. package/dist/workflow-engine/tasks/listen.d.ts +34 -0
  508. package/dist/workflow-engine/tasks/listen.js +119 -0
  509. package/dist/workflow-engine/tasks/listen.js.map +1 -0
  510. package/dist/workflow-engine/tasks/raise.d.ts +18 -0
  511. package/dist/workflow-engine/tasks/raise.js +60 -0
  512. package/dist/workflow-engine/tasks/raise.js.map +1 -0
  513. package/dist/workflow-engine/tasks/run.d.ts +39 -0
  514. package/dist/workflow-engine/tasks/run.js +114 -0
  515. package/dist/workflow-engine/tasks/run.js.map +1 -0
  516. package/dist/workflow-engine/tasks/set.d.ts +15 -0
  517. package/dist/workflow-engine/tasks/set.js +31 -0
  518. package/dist/workflow-engine/tasks/set.js.map +1 -0
  519. package/dist/workflow-engine/tasks/switch.d.ts +25 -0
  520. package/dist/workflow-engine/tasks/switch.js +76 -0
  521. package/dist/workflow-engine/tasks/switch.js.map +1 -0
  522. package/dist/workflow-engine/tasks/try.d.ts +49 -0
  523. package/dist/workflow-engine/tasks/try.js +189 -0
  524. package/dist/workflow-engine/tasks/try.js.map +1 -0
  525. package/dist/workflow-engine/tasks/wait.d.ts +24 -0
  526. package/dist/workflow-engine/tasks/wait.js +39 -0
  527. package/dist/workflow-engine/tasks/wait.js.map +1 -0
  528. package/dist/workflow-engine/types.d.ts +682 -0
  529. package/dist/workflow-engine/types.js +47 -0
  530. package/dist/workflow-engine/types.js.map +1 -0
  531. package/dist/workflows/call-agent-orchestrator.d.ts +31 -0
  532. package/dist/workflows/call-agent-orchestrator.js +214 -0
  533. package/dist/workflows/call-agent-orchestrator.js.map +1 -0
  534. package/dist/workflows/connect-mcp-server.d.ts +20 -0
  535. package/dist/workflows/connect-mcp-server.js +113 -0
  536. package/dist/workflows/connect-mcp-server.js.map +1 -0
  537. package/dist/workflows/engine-core.d.ts +36 -0
  538. package/dist/workflows/engine-core.js +272 -0
  539. package/dist/workflows/engine-core.js.map +1 -0
  540. package/dist/workflows/execute-from-execution.d.ts +32 -0
  541. package/dist/workflows/execute-from-execution.js +71 -0
  542. package/dist/workflows/execute-from-execution.js.map +1 -0
  543. package/dist/workflows/execute-serverless-workflow.d.ts +32 -0
  544. package/dist/workflows/execute-serverless-workflow.js +36 -0
  545. package/dist/workflows/execute-serverless-workflow.js.map +1 -0
  546. package/dist/workflows/human-input-orchestrator.d.ts +19 -0
  547. package/dist/workflows/human-input-orchestrator.js +59 -0
  548. package/dist/workflows/human-input-orchestrator.js.map +1 -0
  549. package/dist/workflows/index.d.ts +22 -0
  550. package/dist/workflows/index.js +23 -0
  551. package/dist/workflows/index.js.map +1 -0
  552. package/dist/workflows/listen-orchestrator.d.ts +29 -0
  553. package/dist/workflows/listen-orchestrator.js +143 -0
  554. package/dist/workflows/listen-orchestrator.js.map +1 -0
  555. package/dist/workflows/metrics-sink.d.ts +33 -0
  556. package/dist/workflows/metrics-sink.js +21 -0
  557. package/dist/workflows/metrics-sink.js.map +1 -0
  558. package/dist/workflows/run-orchestrator.d.ts +15 -0
  559. package/dist/workflows/run-orchestrator.js +27 -0
  560. package/dist/workflows/run-orchestrator.js.map +1 -0
  561. package/dist/workflows/types.d.ts +46 -0
  562. package/dist/workflows/types.js +15 -0
  563. package/dist/workflows/types.js.map +1 -0
  564. package/dist/workflows/workflow-signals.d.ts +29 -0
  565. package/dist/workflows/workflow-signals.js +46 -0
  566. package/dist/workflows/workflow-signals.js.map +1 -0
  567. package/package.json +108 -0
  568. package/src/__test-utils__/__tests__/replay-fetch.test.ts +155 -0
  569. package/src/__test-utils__/mock-client.ts +44 -0
  570. package/src/__test-utils__/mock-workspace.ts +28 -0
  571. package/src/__test-utils__/proto-helpers.ts +41 -0
  572. package/src/__test-utils__/replay-fetch.ts +523 -0
  573. package/src/__tests__/bootstrap.test.ts +221 -0
  574. package/src/__tests__/claimcheck-codec.test.ts +257 -0
  575. package/src/__tests__/config.test.ts +150 -0
  576. package/src/__tests__/deterministic-eval-llm.test.ts +269 -0
  577. package/src/__tests__/deterministic-mcp-hitl.test.ts +405 -0
  578. package/src/__tests__/golden-e2e.test.ts +250 -0
  579. package/src/__tests__/ipc-protocol-fixtures.test.ts +66 -0
  580. package/src/__tests__/ipc-protocol.test.ts +32 -0
  581. package/src/__tests__/otel-metrics.test.ts +40 -0
  582. package/src/__tests__/runner-manager.test.ts +55 -0
  583. package/src/__tests__/runner-token-coordinator.test.ts +166 -0
  584. package/src/__tests__/runner.test.ts +182 -0
  585. package/src/__tests__/worker.test.ts +18 -0
  586. package/src/activities/__tests__/call-agent-contracts.test.ts +483 -0
  587. package/src/activities/__tests__/call-agent.test.ts +263 -0
  588. package/src/activities/__tests__/call-function.test.ts +47 -0
  589. package/src/activities/__tests__/call-grpc.test.ts +39 -0
  590. package/src/activities/__tests__/call-http.test.ts +288 -0
  591. package/src/activities/__tests__/call-llm.test.ts +301 -0
  592. package/src/activities/__tests__/classify-tool-approvals.test.ts +430 -0
  593. package/src/activities/__tests__/discover-mcp-server.test.ts +641 -0
  594. package/src/activities/__tests__/ensure-thread.test.ts +96 -0
  595. package/src/activities/__tests__/error-classifier.test.ts +372 -0
  596. package/src/activities/__tests__/evaluate-expressions.test.ts +114 -0
  597. package/src/activities/__tests__/hydrate-workflow-execution.test.ts +321 -0
  598. package/src/activities/__tests__/notification.test.ts +151 -0
  599. package/src/activities/__tests__/workflow-event-activities.test.ts +664 -0
  600. package/src/activities/call-agent-status.ts +130 -0
  601. package/src/activities/call-agent.ts +302 -0
  602. package/src/activities/call-eval.ts +333 -0
  603. package/src/activities/call-function.ts +73 -0
  604. package/src/activities/call-grpc.ts +140 -0
  605. package/src/activities/call-http.ts +185 -0
  606. package/src/activities/call-llm.ts +379 -0
  607. package/src/activities/call-transform.ts +54 -0
  608. package/src/activities/call-validate.ts +223 -0
  609. package/src/activities/classify-tool-approvals.ts +319 -0
  610. package/src/activities/discover-mcp-server.ts +411 -0
  611. package/src/activities/emit-event.ts +195 -0
  612. package/src/activities/ensure-thread.ts +45 -0
  613. package/src/activities/evaluate-expressions.ts +47 -0
  614. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +188 -0
  615. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +111 -0
  616. package/src/activities/execute-cursor/__tests__/cursor-baseurl-routing.test.ts +86 -0
  617. package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +64 -0
  618. package/src/activities/execute-cursor/__tests__/cursor-mode.test.ts +95 -0
  619. package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +90 -0
  620. package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +242 -0
  621. package/src/activities/execute-cursor/__tests__/error-classifier-introspection.test.ts +156 -0
  622. package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +211 -0
  623. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +298 -0
  624. package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +360 -0
  625. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +657 -0
  626. package/src/activities/execute-cursor/__tests__/model-pricing.test.ts +92 -0
  627. package/src/activities/execute-cursor/__tests__/prompt-builder-delegation.test.ts +101 -0
  628. package/src/activities/execute-cursor/__tests__/runner-error-regressions.test.ts +144 -0
  629. package/src/activities/execute-cursor/__tests__/session-lifecycle.test.ts +65 -0
  630. package/src/activities/execute-cursor/__tests__/skill-resolver.test.ts +265 -0
  631. package/src/activities/execute-cursor/__tests__/subagent-config.test.ts +107 -0
  632. package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +498 -0
  633. package/src/activities/execute-cursor/__tests__/workspace-provision.test.ts +283 -0
  634. package/src/activities/execute-cursor/approval-policy.ts +224 -0
  635. package/src/activities/execute-cursor/approval-state.ts +311 -0
  636. package/src/activities/execute-cursor/attachment-resolver.ts +78 -0
  637. package/src/activities/execute-cursor/blueprint-resolver.ts +234 -0
  638. package/src/activities/execute-cursor/connect-backfill.ts +49 -0
  639. package/src/activities/execute-cursor/cursor-event-recorder.ts +83 -0
  640. package/src/activities/execute-cursor/cursor-mode.ts +42 -0
  641. package/src/activities/execute-cursor/delta-enricher.ts +307 -0
  642. package/src/activities/execute-cursor/env-resolver.ts +64 -0
  643. package/src/activities/execute-cursor/error-classifier.ts +247 -0
  644. package/src/activities/execute-cursor/fetch-interceptor.ts +382 -0
  645. package/src/activities/execute-cursor/hitl-diagnostics.ts +82 -0
  646. package/src/activities/execute-cursor/hook-script.ts +159 -0
  647. package/src/activities/execute-cursor/http2-interceptor.ts +253 -0
  648. package/src/activities/execute-cursor/index.ts +1439 -0
  649. package/src/activities/execute-cursor/mcp-config.ts +66 -0
  650. package/src/activities/execute-cursor/mcp-resolver.ts +271 -0
  651. package/src/activities/execute-cursor/message-translator.ts +896 -0
  652. package/src/activities/execute-cursor/model-pricing-data.ts +167 -0
  653. package/src/activities/execute-cursor/model-pricing.ts +167 -0
  654. package/src/activities/execute-cursor/placeholder-resolver.ts +109 -0
  655. package/src/activities/execute-cursor/prompt-builder.ts +349 -0
  656. package/src/activities/execute-cursor/rejection-capture.ts +100 -0
  657. package/src/activities/execute-cursor/session-lifecycle.ts +429 -0
  658. package/src/activities/execute-cursor/skill-resolver.ts +176 -0
  659. package/src/activities/execute-cursor/subagent-config.ts +62 -0
  660. package/src/activities/execute-cursor/todo-tracker.ts +133 -0
  661. package/src/activities/execute-cursor/usage-accumulator.ts +126 -0
  662. package/src/activities/execute-cursor/workspace-provision.ts +55 -0
  663. package/src/activities/execute-cursor/workspace-setup.ts +75 -0
  664. package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +281 -0
  665. package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +720 -0
  666. package/src/activities/execute-deep-agent/__tests__/auto-publish.test.ts +146 -0
  667. package/src/activities/execute-deep-agent/__tests__/environment.test.ts +103 -0
  668. package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +150 -0
  669. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +150 -0
  670. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +157 -0
  671. package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +223 -0
  672. package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +244 -0
  673. package/src/activities/execute-deep-agent/__tests__/index.test.ts +91 -0
  674. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +240 -0
  675. package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +112 -0
  676. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +208 -0
  677. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +1771 -0
  678. package/src/activities/execute-deep-agent/__tests__/streaming-scheduler.test.ts +199 -0
  679. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +527 -0
  680. package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +508 -0
  681. package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +474 -0
  682. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +734 -0
  683. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +71 -0
  684. package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +323 -0
  685. package/src/activities/execute-deep-agent/__tests__/v3-event-recorder.test.ts +186 -0
  686. package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +324 -0
  687. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +504 -0
  688. package/src/activities/execute-deep-agent/__tests__/writeback-coordinator.test.ts +399 -0
  689. package/src/activities/execute-deep-agent/attachment-injector.ts +470 -0
  690. package/src/activities/execute-deep-agent/auto-publish.ts +80 -0
  691. package/src/activities/execute-deep-agent/environment.ts +67 -0
  692. package/src/activities/execute-deep-agent/event-recorder.ts +95 -0
  693. package/src/activities/execute-deep-agent/execution-state.ts +87 -0
  694. package/src/activities/execute-deep-agent/execution-status-writer.ts +19 -0
  695. package/src/activities/execute-deep-agent/hitl.ts +221 -0
  696. package/src/activities/execute-deep-agent/index.ts +342 -0
  697. package/src/activities/execute-deep-agent/inline-publisher.ts +134 -0
  698. package/src/activities/execute-deep-agent/post-stream.ts +109 -0
  699. package/src/activities/execute-deep-agent/prompt-builder.ts +264 -0
  700. package/src/activities/execute-deep-agent/setup.ts +599 -0
  701. package/src/activities/execute-deep-agent/status-builder-shared.ts +136 -0
  702. package/src/activities/execute-deep-agent/status-builder.ts +412 -0
  703. package/src/activities/execute-deep-agent/streaming-scheduler.ts +159 -0
  704. package/src/activities/execute-deep-agent/streaming-side-effects.ts +89 -0
  705. package/src/activities/execute-deep-agent/streaming-terminal.ts +96 -0
  706. package/src/activities/execute-deep-agent/streaming-v3.ts +272 -0
  707. package/src/activities/execute-deep-agent/streaming.ts +303 -0
  708. package/src/activities/execute-deep-agent/subagent-tracker.ts +445 -0
  709. package/src/activities/execute-deep-agent/subagent-transformer.ts +648 -0
  710. package/src/activities/execute-deep-agent/subagent-wiring.ts +56 -0
  711. package/src/activities/execute-deep-agent/v3-event-recorder.ts +111 -0
  712. package/src/activities/execute-deep-agent/v3-events.ts +153 -0
  713. package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +264 -0
  714. package/src/activities/execute-deep-agent/v3-status-builder.ts +490 -0
  715. package/src/activities/execute-deep-agent/writeback-coordinator.ts +420 -0
  716. package/src/activities/hydrate-workflow-execution.ts +306 -0
  717. package/src/activities/notification.ts +71 -0
  718. package/src/activities/promote-task-output.ts +126 -0
  719. package/src/activities/run-command.ts +148 -0
  720. package/src/activities/workflow-event-activities.ts +481 -0
  721. package/src/bootstrap.ts +173 -0
  722. package/src/budget/__tests__/tracker.test.ts +293 -0
  723. package/src/budget/index.ts +9 -0
  724. package/src/budget/tracker.ts +171 -0
  725. package/src/claimcheck/compressor.ts +9 -0
  726. package/src/claimcheck/config.ts +20 -0
  727. package/src/claimcheck/index.ts +3 -0
  728. package/src/claimcheck/payload-codec.ts +107 -0
  729. package/src/client/__tests__/server-contracts.test.ts +149 -0
  730. package/src/client/__tests__/stigmer-client.test.ts +142 -0
  731. package/src/client/server-contracts.ts +125 -0
  732. package/src/client/stigmer-client.ts +339 -0
  733. package/src/config.ts +185 -0
  734. package/src/idle-watchdog.ts +28 -0
  735. package/src/index.ts +48 -0
  736. package/src/interceptors/workflow-metrics-sink.ts +56 -0
  737. package/src/ipc-protocol-fixtures.ts +117 -0
  738. package/src/ipc-protocol.ts +113 -0
  739. package/src/main.ts +324 -0
  740. package/src/middleware/__tests__/approval-gate.test.ts +231 -0
  741. package/src/middleware/__tests__/cost-cap.test.ts +192 -0
  742. package/src/middleware/__tests__/error-hints.test.ts +90 -0
  743. package/src/middleware/__tests__/execution-budget.test.ts +138 -0
  744. package/src/middleware/__tests__/graceful-stop.test.ts +105 -0
  745. package/src/middleware/__tests__/loop-detection.test.ts +137 -0
  746. package/src/middleware/__tests__/otel-spans.test.ts +89 -0
  747. package/src/middleware/__tests__/think-tool.test.ts +26 -0
  748. package/src/middleware/__tests__/tool-truncation.test.ts +112 -0
  749. package/src/middleware/approval-gate.ts +179 -0
  750. package/src/middleware/cost-cap.ts +213 -0
  751. package/src/middleware/error-hints.ts +136 -0
  752. package/src/middleware/execution-budget.ts +176 -0
  753. package/src/middleware/graceful-stop.ts +86 -0
  754. package/src/middleware/index.ts +70 -0
  755. package/src/middleware/loop-detection.ts +192 -0
  756. package/src/middleware/otel-spans.ts +205 -0
  757. package/src/middleware/think-tool.ts +38 -0
  758. package/src/middleware/tool-truncation.ts +94 -0
  759. package/src/middleware/types.ts +114 -0
  760. package/src/notification/__tests__/provider.test.ts +85 -0
  761. package/src/notification/__tests__/webhook.test.ts +127 -0
  762. package/src/notification/index.ts +15 -0
  763. package/src/notification/provider.ts +52 -0
  764. package/src/notification/webhook.ts +61 -0
  765. package/src/otel-metrics.ts +73 -0
  766. package/src/otel.ts +194 -0
  767. package/src/runner-manager.ts +652 -0
  768. package/src/runner-token-coordinator.ts +135 -0
  769. package/src/runner.ts +380 -0
  770. package/src/shared/__tests__/approval-policy.test.ts +256 -0
  771. package/src/shared/__tests__/artifact-storage-extended.test.ts +208 -0
  772. package/src/shared/__tests__/artifact-storage.test.ts +365 -0
  773. package/src/shared/__tests__/connect-backfill.test.ts +346 -0
  774. package/src/shared/__tests__/extract-json.test.ts +153 -0
  775. package/src/shared/__tests__/grpc-retry-extended.test.ts +176 -0
  776. package/src/shared/__tests__/grpc-retry.test.ts +172 -0
  777. package/src/shared/__tests__/json-schema-to-zod.test.ts +227 -0
  778. package/src/shared/__tests__/llm-proxy.test.ts +179 -0
  779. package/src/shared/__tests__/mcp-manager.test.ts +154 -0
  780. package/src/shared/__tests__/model-pricing.test.ts +85 -0
  781. package/src/shared/__tests__/model-registry.test.ts +197 -0
  782. package/src/shared/__tests__/placeholder-resolver.test.ts +210 -0
  783. package/src/shared/__tests__/plan-artifact.test.ts +142 -0
  784. package/src/shared/__tests__/skill-relevance.test.ts +292 -0
  785. package/src/shared/__tests__/skill-writer.test.ts +349 -0
  786. package/src/shared/__tests__/status.test.ts +142 -0
  787. package/src/shared/__tests__/subagent-gate.test.ts +112 -0
  788. package/src/shared/__tests__/tool-kind.test.ts +58 -0
  789. package/src/shared/__tests__/zip-extract.test.ts +204 -0
  790. package/src/shared/approval-policy.ts +146 -0
  791. package/src/shared/artifact-storage.ts +207 -0
  792. package/src/shared/checkpointer/__tests__/factory.test.ts +42 -0
  793. package/src/shared/checkpointer/__tests__/http-saver.test.ts +176 -0
  794. package/src/shared/checkpointer/factory.ts +73 -0
  795. package/src/shared/checkpointer/http-saver.ts +349 -0
  796. package/src/shared/checkpointer/types.ts +12 -0
  797. package/src/shared/connect-backfill.ts +162 -0
  798. package/src/shared/extract-json.ts +153 -0
  799. package/src/shared/grpc-retry.ts +113 -0
  800. package/src/shared/heartbeat.ts +70 -0
  801. package/src/shared/json-schema-to-zod.ts +53 -0
  802. package/src/shared/llm-proxy.ts +138 -0
  803. package/src/shared/mcp-manager.ts +150 -0
  804. package/src/shared/mcp-resolver.ts +150 -0
  805. package/src/shared/model-pricing-data.ts +109 -0
  806. package/src/shared/model-pricing.ts +81 -0
  807. package/src/shared/model-registry.ts +214 -0
  808. package/src/shared/placeholder-resolver.ts +102 -0
  809. package/src/shared/plan-artifact.ts +120 -0
  810. package/src/shared/skill-relevance.ts +222 -0
  811. package/src/shared/skill-writer.ts +300 -0
  812. package/src/shared/status.ts +94 -0
  813. package/src/shared/subagent-gate.ts +117 -0
  814. package/src/shared/tool-kind.ts +91 -0
  815. package/src/shared/workspace/__tests__/file-tree.test.ts +210 -0
  816. package/src/shared/workspace/__tests__/git-source.test.ts +423 -0
  817. package/src/shared/workspace/__tests__/local-backend-platform.test.ts +259 -0
  818. package/src/shared/workspace/__tests__/local-backend.test.ts +154 -0
  819. package/src/shared/workspace/__tests__/platform-mount.test.ts +378 -0
  820. package/src/shared/workspace/__tests__/provisioner.test.ts +145 -0
  821. package/src/shared/workspace/file-tree.ts +116 -0
  822. package/src/shared/workspace/local-backend.ts +140 -0
  823. package/src/shared/workspace/platform-dir.ts +38 -0
  824. package/src/shared/workspace/platform-mount.ts +190 -0
  825. package/src/shared/workspace/provisioner.ts +150 -0
  826. package/src/shared/workspace/sources/empty.ts +20 -0
  827. package/src/shared/workspace/sources/git.ts +285 -0
  828. package/src/shared/workspace/sources/local-path.ts +89 -0
  829. package/src/shared/workspace/types.ts +69 -0
  830. package/src/shared/zip-extract.ts +193 -0
  831. package/src/worker.ts +98 -0
  832. package/src/workflow-engine/__tests__/do-executor-recovery.test.ts +382 -0
  833. package/src/workflow-engine/__tests__/do-executor.test.ts +963 -0
  834. package/src/workflow-engine/__tests__/errors.test.ts +174 -0
  835. package/src/workflow-engine/__tests__/expression.test.ts +776 -0
  836. package/src/workflow-engine/__tests__/for.test.ts +575 -0
  837. package/src/workflow-engine/__tests__/fork.test.ts +838 -0
  838. package/src/workflow-engine/__tests__/golden-execution.test.ts +1085 -0
  839. package/src/workflow-engine/__tests__/jq-wasm-spike.test.ts +90 -0
  840. package/src/workflow-engine/__tests__/loader.test.ts +1393 -0
  841. package/src/workflow-engine/__tests__/pause-resume.test.ts +267 -0
  842. package/src/workflow-engine/__tests__/recovery.test.ts +115 -0
  843. package/src/workflow-engine/__tests__/resolve.test.ts +432 -0
  844. package/src/workflow-engine/__tests__/retry.test.ts +306 -0
  845. package/src/workflow-engine/__tests__/state.test.ts +174 -0
  846. package/src/workflow-engine/__tests__/task-status-accumulator.test.ts +373 -0
  847. package/src/workflow-engine/__tests__/tasks/call-agent-output.test.ts +120 -0
  848. package/src/workflow-engine/__tests__/tasks/call-agent.test.ts +816 -0
  849. package/src/workflow-engine/__tests__/tasks/call-function.test.ts +205 -0
  850. package/src/workflow-engine/__tests__/tasks/call-grpc.test.ts +133 -0
  851. package/src/workflow-engine/__tests__/tasks/call-http.test.ts +150 -0
  852. package/src/workflow-engine/__tests__/tasks/emit-event.test.ts +322 -0
  853. package/src/workflow-engine/__tests__/tasks/human-input.test.ts +416 -0
  854. package/src/workflow-engine/__tests__/tasks/listen.test.ts +422 -0
  855. package/src/workflow-engine/__tests__/tasks/raise.test.ts +166 -0
  856. package/src/workflow-engine/__tests__/tasks/run.test.ts +272 -0
  857. package/src/workflow-engine/__tests__/tasks/set.test.ts +127 -0
  858. package/src/workflow-engine/__tests__/tasks/switch.test.ts +277 -0
  859. package/src/workflow-engine/__tests__/tasks/try.test.ts +590 -0
  860. package/src/workflow-engine/__tests__/tasks/wait.test.ts +173 -0
  861. package/src/workflow-engine/clone.ts +18 -0
  862. package/src/workflow-engine/do-executor.ts +569 -0
  863. package/src/workflow-engine/duration.ts +22 -0
  864. package/src/workflow-engine/error-utils.ts +97 -0
  865. package/src/workflow-engine/errors.ts +130 -0
  866. package/src/workflow-engine/expression-utils.ts +129 -0
  867. package/src/workflow-engine/expression.ts +430 -0
  868. package/src/workflow-engine/loader.ts +524 -0
  869. package/src/workflow-engine/recovery.ts +80 -0
  870. package/src/workflow-engine/resolve.ts +342 -0
  871. package/src/workflow-engine/retry.ts +109 -0
  872. package/src/workflow-engine/state.ts +56 -0
  873. package/src/workflow-engine/task-factory.ts +160 -0
  874. package/src/workflow-engine/task-status-accumulator.ts +204 -0
  875. package/src/workflow-engine/tasks/call-agent-output.ts +132 -0
  876. package/src/workflow-engine/tasks/call-agent.ts +221 -0
  877. package/src/workflow-engine/tasks/call-function.ts +107 -0
  878. package/src/workflow-engine/tasks/call-grpc.ts +47 -0
  879. package/src/workflow-engine/tasks/call-http.ts +51 -0
  880. package/src/workflow-engine/tasks/for.ts +244 -0
  881. package/src/workflow-engine/tasks/fork.ts +228 -0
  882. package/src/workflow-engine/tasks/human-input.ts +147 -0
  883. package/src/workflow-engine/tasks/listen.ts +166 -0
  884. package/src/workflow-engine/tasks/raise.ts +81 -0
  885. package/src/workflow-engine/tasks/run.ts +142 -0
  886. package/src/workflow-engine/tasks/set.ts +47 -0
  887. package/src/workflow-engine/tasks/switch.ts +102 -0
  888. package/src/workflow-engine/tasks/try.ts +274 -0
  889. package/src/workflow-engine/tasks/wait.ts +53 -0
  890. package/src/workflow-engine/types.ts +911 -0
  891. package/src/workflows/__tests__/connect-mcp-server.test.ts +359 -0
  892. package/src/workflows/__tests__/execute-serverless-workflow.test.ts +277 -0
  893. package/src/workflows/call-agent-orchestrator.ts +283 -0
  894. package/src/workflows/connect-mcp-server.ts +152 -0
  895. package/src/workflows/engine-core.ts +406 -0
  896. package/src/workflows/execute-from-execution.ts +101 -0
  897. package/src/workflows/execute-serverless-workflow.ts +60 -0
  898. package/src/workflows/human-input-orchestrator.ts +76 -0
  899. package/src/workflows/index.ts +32 -0
  900. package/src/workflows/listen-orchestrator.ts +200 -0
  901. package/src/workflows/metrics-sink.ts +48 -0
  902. package/src/workflows/run-orchestrator.ts +34 -0
  903. package/src/workflows/types.ts +64 -0
  904. package/src/workflows/workflow-signals.ts +55 -0
@@ -0,0 +1,1176 @@
1
+ /**
2
+ * ExecuteCursor Temporal activity — the core of the cursor-runner service.
3
+ *
4
+ * Implements the same Slim-Payload Pattern as ExecuteGraphton:
5
+ * - Receives only executionId + harnessStateId (Cursor agentId)
6
+ * - Hydrates execution from DB via gRPC
7
+ * - Resolves full agent blueprint (instructions, MCP servers, skills, sub-agents)
8
+ * - Runs the Cursor agent, streams events, reports status
9
+ * - Returns slim AgentExecutionStatus to workflow
10
+ *
11
+ * Durable HITL Model:
12
+ * When a tool requires approval, the preToolUse hook denies it. The activity
13
+ * captures the denied tool details, reports WAITING_FOR_APPROVAL, and RETURNS
14
+ * to the workflow. The workflow waits for the approvalGateResolved signal,
15
+ * then reinvokes this activity. On reinvocation, the activity resumes the
16
+ * Cursor Agent and prompts it to execute the approved tool.
17
+ *
18
+ * This is identical to the LangGraph flow from the workflow's perspective.
19
+ *
20
+ * Durable Continuation Model:
21
+ * Conversation continuity is carried by the Cursor SDK's native local agent
22
+ * state, whose SQLite store is persisted on the durable workspace volume
23
+ * (see resolvePlatformOptions) so Agent.resume() survives pod restart,
24
+ * reschedule, and snapshot restore. When resume fails (store lost/corrupted
25
+ * or agent unknown), resolveAgent() creates a fresh agent and the next turn
26
+ * starts from the user message plus re-injected instructions.
27
+ */
28
+ import { heartbeat, Context, CancelledFailure } from "@temporalio/activity";
29
+ import { create } from "@bufbuild/protobuf";
30
+ import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
31
+ import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
32
+ import { ExecutionControlSignal, ExecutionPhase, InteractionMode, MessageType, ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
33
+ import { StigmerClient } from "../../client/stigmer-client.js";
34
+ import { resolveAgent } from "./session-lifecycle.js";
35
+ import { CursorMode } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
36
+ import { determineCursorMode, isCloudMode } from "./cursor-mode.js";
37
+ import { MessageAccumulator, reconcileDeniedToolCalls, cancelInProgressSubAgentProtos } from "./message-translator.js";
38
+ import { utcTimestamp, persistStatus, reportSetupProgress, slimStatus } from "../../shared/status.js";
39
+ import { createArtifactStorage, loadArtifactStorageConfig } from "../../shared/artifact-storage.js";
40
+ import { publishPlanArtifact } from "../../shared/plan-artifact.js";
41
+ import { DeltaEnricher } from "./delta-enricher.js";
42
+ import { TodoTracker } from "./todo-tracker.js";
43
+ import { createCursorEventRecorder } from "./cursor-event-recorder.js";
44
+ import { resolveMcpServers, validateMcpServerEnv } from "./mcp-resolver.js";
45
+ import { mergeApprovalPolicies } from "./approval-policy.js";
46
+ import { hasApproveAllDecision } from "../../shared/approval-policy.js";
47
+ import { backfillMcpServersIfNeeded } from "./connect-backfill.js";
48
+ import { resolveExecutionEnv } from "./env-resolver.js";
49
+ import { resolveBlueprint } from "./blueprint-resolver.js";
50
+ import { buildCursorSubAgentDefinitions } from "./subagent-config.js";
51
+ import { resolveSkills } from "./skill-resolver.js";
52
+ import { resolveAttachments } from "./attachment-resolver.js";
53
+ import { buildEnhancedPrompt, buildReinvocationPrompt } from "./prompt-builder.js";
54
+ import { writeHooksToWorkspace } from "./workspace-setup.js";
55
+ import { buildApprovalState, buildApprovalGrants, readDenialLedger, reconstructAdjudicatedApprovals } from "./approval-state.js";
56
+ import { provisionCursorWorkspace } from "./workspace-provision.js";
57
+ import { setInterceptorExecutionId, runWithExecutionContext } from "./fetch-interceptor.js";
58
+ import { closeProxySessions } from "./http2-interceptor.js";
59
+ import { resolveModelId, ensureLoaded as ensurePricingLoaded } from "./model-pricing.js";
60
+ import { UsageAccumulator } from "./usage-accumulator.js";
61
+ import { StreamingUsageSummarySchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/usage_pb";
62
+ import { activityStarted, activityFinished } from "../../idle-watchdog.js";
63
+ import { getCapturedRejection, clearCapturedRejection } from "./rejection-capture.js";
64
+ import { synthesizeError, formatClassifiedError, shouldRetryWithFreshAgent } from "./error-classifier.js";
65
+ import { createAgent, createCloudAgent } from "./session-lifecycle.js";
66
+ import { setMaxListeners } from "node:events";
67
+ import { startHeartbeat } from "../../shared/heartbeat.js";
68
+ import { getShutdownSignalForQueue } from "../../runner-manager.js";
69
+ /**
70
+ * Creates the activity functions bound to the runner config.
71
+ * Returned object is passed to Temporal Worker.create({ activities }).
72
+ */
73
+ export function createCursorActivities(config) {
74
+ const client = new StigmerClient({
75
+ endpoint: config.stigmerBackendEndpoint,
76
+ token: config.stigmerToken,
77
+ tokenRef: config.stigmerTokenRef,
78
+ });
79
+ return {
80
+ ExecuteCursor: async (executionId, threadId) => {
81
+ activityStarted();
82
+ try {
83
+ return await executeCursor(config, client, executionId, threadId);
84
+ }
85
+ finally {
86
+ activityFinished();
87
+ }
88
+ },
89
+ };
90
+ }
91
+ async function executeCursor(config, client, executionId, threadId) {
92
+ console.log(`ExecuteCursor started: execution=${executionId}, threadId=${threadId || "(new)"}`);
93
+ // Ensure fresh HTTP/2 transport — prevents a degraded session from a
94
+ // prior workflow task from poisoning this execution's agent stream.
95
+ closeProxySessions();
96
+ setInterceptorExecutionId(executionId);
97
+ return runWithExecutionContext(executionId, () => executeCursorInner(config, client, executionId, threadId));
98
+ }
99
+ async function executeCursorInner(config, client, executionId, threadId) {
100
+ const status = create(AgentExecutionStatusSchema, {
101
+ phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
102
+ startedAt: utcTimestamp(),
103
+ });
104
+ let sessionId;
105
+ let session;
106
+ let pauseDetected = false;
107
+ let workerShutdownDetected = false;
108
+ let periodicHeartbeat;
109
+ // Carries model/mode/agentId out to the outer catch so a thrown CursorSdkError
110
+ // can be classified with the same context as the run.wait() error path.
111
+ let errorContext = { model: "default", mode: "local", agentId: "" };
112
+ try {
113
+ // Phase 1: Hydrate execution from DB
114
+ await reportSetupProgress(client, executionId, "Fetching execution");
115
+ const execution = await client.getExecution(executionId);
116
+ const spec = execution.spec;
117
+ sessionId = spec.sessionId;
118
+ // Phase 2: Load session and resolve full agent blueprint
119
+ await reportSetupProgress(client, executionId, "Resolving agent blueprint");
120
+ session = await client.getSession(sessionId);
121
+ const blueprint = await resolveBlueprint(client, session, config.workspaceRootDir);
122
+ // Phase 2b: Resolve execution environment (MCP server credentials)
123
+ await reportSetupProgress(client, executionId, "Resolving environment");
124
+ const { envVars, secretKeys } = await resolveExecutionEnv(client, executionId);
125
+ heartbeat();
126
+ // Phase 2c: Provision the workspace (clone git repos / mount local paths)
127
+ // so the LOCAL Cursor agent operates on the actual repo. Cursor previously
128
+ // relied on cloud agents to clone git-repo workspace entries; with cloud
129
+ // disabled the runner must provision the workspace itself, mirroring the
130
+ // native harness. Git provisioning is idempotent across multi-turn and
131
+ // HITL reinvocations.
132
+ await reportSetupProgress(client, executionId, "Provisioning workspace");
133
+ blueprint.workspaceDirs = await provisionCursorWorkspace(config, session, envVars, sessionId ?? "");
134
+ heartbeat();
135
+ // Set OTel baggage so downstream calls carry execution context.
136
+ try {
137
+ const { setBaggage, BAGGAGE_EXECUTION_ID, BAGGAGE_SESSION_ID, BAGGAGE_ORG_ID } = await import("../../otel.js");
138
+ await setBaggage({
139
+ [BAGGAGE_EXECUTION_ID]: executionId,
140
+ [BAGGAGE_SESSION_ID]: sessionId ?? "",
141
+ [BAGGAGE_ORG_ID]: session?.metadata?.org ?? "",
142
+ });
143
+ }
144
+ catch {
145
+ // Tracing not initialized — silently skip.
146
+ }
147
+ // Cloud Cursor agents are disabled platform-wide (see determineCursorMode),
148
+ // so every session runs LOCAL. We intentionally ignore any persisted
149
+ // cursor_mode here so a session can never route to the cloud path while
150
+ // it is disabled — even one that was created when cloud was enabled.
151
+ const cursorMode = determineCursorMode(blueprint.sessionSpec.workspaceEntries, config.cloudModeEnabled);
152
+ const agentMode = isCloudMode(cursorMode) ? "cloud" : "local";
153
+ heartbeat();
154
+ // Phase 3: Check if this is a reinvocation after approval
155
+ const isReinvocation = !!threadId;
156
+ let approvalDecisions;
157
+ // Adjudicated approvals reconstructed from the tool calls (the source of
158
+ // truth for a decision). The backend projects pending_approvals from
159
+ // tool-call status and clears decided entries, so pending_approvals is empty
160
+ // by reinvocation time — the decision survives only on the tool call. This
161
+ // feeds both the grant builder and the reinvocation prompt below.
162
+ let adjudicatedApprovals = [];
163
+ if (isReinvocation) {
164
+ const existingStatus = execution.status;
165
+ const adjudicated = reconstructAdjudicatedApprovals(existingStatus?.messages ?? []);
166
+ if (adjudicated.decisions.size > 0) {
167
+ approvalDecisions = adjudicated.decisions;
168
+ adjudicatedApprovals = adjudicated.pendingApprovals;
169
+ const hasReject = [...approvalDecisions.values()].some((a) => a === ApprovalAction.REJECT);
170
+ if (hasReject) {
171
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
172
+ status.error = "Execution rejected by user";
173
+ status.completedAt = utcTimestamp();
174
+ status.messages.push(create(AgentMessageSchema, {
175
+ type: MessageType.MESSAGE_SYSTEM,
176
+ content: "Execution was rejected by the user during tool approval.",
177
+ timestamp: utcTimestamp(),
178
+ }));
179
+ await persistStatus(client, executionId, status);
180
+ return slimStatus(status);
181
+ }
182
+ }
183
+ }
184
+ // Phase 4: Resolve MCP servers with approval policies
185
+ await reportSetupProgress(client, executionId, "Resolving MCP servers");
186
+ let mcpResolution = await resolveMcpServers(client, blueprint.mergedMcpServerUsages, envVars);
187
+ // Phase 4a: Connect backfill for undiscovered MCP servers
188
+ const sessionOrg = session.metadata?.org ?? "";
189
+ mcpResolution = await backfillMcpServersIfNeeded(client, mcpResolution, blueprint.mergedMcpServerUsages, envVars, sessionOrg, heartbeat, secretKeys);
190
+ const mcpConfig = mcpResolution.cursorConfig;
191
+ // Phase 4b: Merge approval policies from all layers.
192
+ //
193
+ // Effective auto-approve is true when EITHER the execution was pre-armed via
194
+ // spec.auto_approve_all OR a user chose APPROVE_ALL ("approve and don't ask
195
+ // again") at some gate earlier in this run. The shared hasApproveAllDecision
196
+ // helper (used by the native harness too) keeps this contract defined once.
197
+ // When true, the merged policy map is empty and the hook state file disables
198
+ // gating for the rest of the run.
199
+ const effectiveAutoApproveAll = (execution.spec?.autoApproveAll ?? false) || hasApproveAllDecision(execution);
200
+ const agentOverrides = blueprint.mergedMcpServerUsages
201
+ .flatMap((u) => u.toolApprovalOverrides ?? []);
202
+ const mergedPolicies = mergeApprovalPolicies(mcpResolution.resolvedServers, agentOverrides, effectiveAutoApproveAll);
203
+ heartbeat();
204
+ // Phase 4c: Validate MCP server env health (diagnostic, non-blocking)
205
+ const mcpWarnings = validateMcpServerEnv(mcpResolution.resolvedServers, blueprint.mergedMcpServerUsages, envVars);
206
+ if (mcpWarnings.length > 0) {
207
+ console.warn(`ExecuteCursor MCP pre-flight warnings: execution=${executionId}\n` +
208
+ mcpWarnings.map((w) => ` - ${w}`).join("\n"));
209
+ }
210
+ // Phase 5: Resolve skills (merged from agent + session)
211
+ await reportSetupProgress(client, executionId, "Resolving skills");
212
+ const primaryWorkspaceDir = blueprint.workspaceDirs[0];
213
+ const skillMetadata = await resolveSkills(client, blueprint.mergedSkillRefs, {
214
+ sessionId,
215
+ primaryWorkspaceDir,
216
+ });
217
+ heartbeat();
218
+ // Phase 5b: Resolve attachments
219
+ const attachmentResults = await resolveAttachments(spec.attachments, sessionId, primaryWorkspaceDir, config.mode);
220
+ const attachmentPaths = attachmentResults.map((a) => a.relativePath);
221
+ // Phase 5c: Ensure model pricing registry is populated before validation
222
+ await ensurePricingLoaded();
223
+ // Phase 6: Validate model selection
224
+ const requestedModel = spec.executionConfig?.modelName || "default";
225
+ const validatedModel = resolveModelId(requestedModel);
226
+ if (validatedModel !== requestedModel) {
227
+ console.log(`ExecuteCursor model resolved: execution=${executionId}, requested="${requestedModel}", using="${validatedModel}"`);
228
+ }
229
+ heartbeat();
230
+ // Phase 7: Resolve Cursor Agent (create, resume, or graceful fallback)
231
+ await reportSetupProgress(client, executionId, "Initializing Cursor agent");
232
+ // In proxy mode, use the stigmer token as the API key — the proxy
233
+ // validates it and injects the real Cursor API key server-side.
234
+ // In direct mode, use the user's own CURSOR_API_KEY.
235
+ const effectiveApiKey = config.proxyEndpoint
236
+ ? (config.stigmerTokenRef?.current ?? config.stigmerToken ?? config.cursorApiKey)
237
+ : config.cursorApiKey;
238
+ if (!effectiveApiKey || effectiveApiKey === "proxy-managed") {
239
+ const source = config.proxyEndpoint ? "proxy (STIGMER_TOKEN)" : "direct (CURSOR_API_KEY)";
240
+ throw new Error(`No Cursor API credential available. Mode=${source}, ` +
241
+ `proxyEndpoint=${config.proxyEndpoint ?? "unset"}, ` +
242
+ `hasStigmerToken=${!!config.stigmerToken}, ` +
243
+ `hasTokenRef=${!!config.stigmerTokenRef?.current}`);
244
+ }
245
+ // Register blueprint sub-agents with the Cursor SDK so the parent can
246
+ // delegate to them by name via the Task tool. Re-supplied on every
247
+ // create/resume (the SDK does not persist agent config across resume).
248
+ const cursorSubAgents = buildCursorSubAgentDefinitions(blueprint.subAgents);
249
+ if (cursorSubAgents) {
250
+ console.log(`ExecuteCursor registering ${Object.keys(cursorSubAgents).length} custom sub-agent(s): ` +
251
+ `execution=${executionId}, names=${Object.keys(cursorSubAgents).join(", ")}`);
252
+ }
253
+ const createOptions = agentMode === "cloud"
254
+ ? {
255
+ apiKey: effectiveApiKey,
256
+ model: validatedModel || undefined,
257
+ repos: blueprint.cloudRepos,
258
+ sessionId,
259
+ mcpServers: mcpConfig,
260
+ agents: cursorSubAgents,
261
+ }
262
+ : {
263
+ apiKey: effectiveApiKey,
264
+ model: validatedModel,
265
+ workspaceDirs: blueprint.workspaceDirs,
266
+ sessionId,
267
+ workspaceRootDir: config.workspaceRootDir,
268
+ mcpServers: mcpConfig,
269
+ agents: cursorSubAgents,
270
+ };
271
+ let resolution = await resolveAgent(threadId, createOptions, agentMode);
272
+ console.log(`ExecuteCursor agent resolved: execution=${executionId}, ` +
273
+ `reason=${resolution.reason}, mode=${resolution.mode}, ` +
274
+ `agentId=${resolution.agentId}, resumed=${resolution.resumed}` +
275
+ (resolution.resumeFailureDetail ? `, failureDetail=${resolution.resumeFailureDetail}` : ""));
276
+ errorContext = { model: validatedModel, mode: agentMode, agentId: resolution.agentId };
277
+ // Phase 8: Write hooks for HITL with policy-aware state. On reinvocation,
278
+ // turn the user's approvals into tool-identity grants so the resumed agent's
279
+ // re-attempt (which carries a fresh tool-call id) is allowed through.
280
+ const approvalGrants = approvalDecisions
281
+ ? buildApprovalGrants(adjudicatedApprovals, approvalDecisions)
282
+ : undefined;
283
+ const approvalState = buildApprovalState(mergedPolicies, effectiveAutoApproveAll, approvalGrants);
284
+ await writeHooksToWorkspace(primaryWorkspaceDir, approvalState);
285
+ // Phase 9: Store new agentId as harness_state_id and persist cursor_mode
286
+ if (resolution.isNew && resolution.agentId) {
287
+ try {
288
+ blueprint.sessionSpec.harnessStateId = resolution.agentId;
289
+ if (blueprint.sessionSpec.cursorMode === CursorMode.UNSPECIFIED) {
290
+ blueprint.sessionSpec.cursorMode = cursorMode;
291
+ }
292
+ // Clear slug to avoid re-validation of potentially invalid
293
+ // server-generated slugs. BuildUpdateStateStep preserves the
294
+ // existing slug from the database record.
295
+ if (blueprint.session.metadata) {
296
+ blueprint.session.metadata.slug = "";
297
+ }
298
+ await client.updateSession(blueprint.session);
299
+ console.log(`Stored Cursor agentId=${resolution.agentId} as harness_state_id, ` +
300
+ `cursorMode=${CursorMode[cursorMode]} on session ${sessionId}`);
301
+ }
302
+ catch (err) {
303
+ console.warn("Failed to persist harness_state_id/cursorMode on session (non-fatal):", err);
304
+ }
305
+ }
306
+ // Phase 9b: Detect structured output schema from execution config
307
+ const structuredOutputSchema = spec.executionConfig?.structuredOutputSchema;
308
+ // Phase 10: Build the prompt
309
+ const interactionMode = spec.executionConfig?.interactionMode
310
+ ?? InteractionMode.UNSPECIFIED;
311
+ const prompt = buildPrompt({
312
+ resolution,
313
+ approvalDecisions,
314
+ instructions: blueprint.instructions,
315
+ userMessage: spec.message,
316
+ skills: skillMetadata,
317
+ subAgents: blueprint.subAgents,
318
+ workspaceDirs: blueprint.workspaceDirs,
319
+ workspaceFileRefs: spec.workspaceFileRefs ?? [],
320
+ attachmentPaths,
321
+ pendingApprovals: adjudicatedApprovals,
322
+ interactionMode,
323
+ });
324
+ // Phase 10a: Inject structured output instruction for Cursor harness
325
+ let effectivePrompt = prompt;
326
+ if (structuredOutputSchema) {
327
+ const schemaStr = JSON.stringify(structuredOutputSchema, null, 2);
328
+ effectivePrompt += `\n\n---\nCRITICAL OUTPUT REQUIREMENT:\nYour final response MUST be a single valid JSON object (no markdown, no commentary, no code fences) that matches this schema:\n${schemaStr}\n\nRespond with ONLY the JSON object. Nothing else.`;
329
+ }
330
+ // Phase 10a2: Log Stigmer preamble size for context trimming diagnostics
331
+ const promptChars = effectivePrompt.length;
332
+ const promptEstimatedTokens = Math.ceil(promptChars / 4);
333
+ console.log(`ExecuteCursor prompt built: execution=${executionId}, ` +
334
+ `chars=${promptChars}, estimatedTokens=${promptEstimatedTokens}, ` +
335
+ `resolution=${resolution.reason}, mode=${resolution.mode}`);
336
+ // Phase 10b: Initialize usage accumulator for runner-side token tracking
337
+ await ensurePricingLoaded();
338
+ const usageAccumulator = new UsageAccumulator(validatedModel);
339
+ // Phase 10c: Start OTel turn span (coarse-grained — wraps entire agent.send + stream)
340
+ const { startCursorTurnSpan } = await import("../../otel.js");
341
+ const turnSpan = await startCursorTurnSpan({
342
+ model: validatedModel,
343
+ mode: agentMode,
344
+ sessionId: sessionId ?? "",
345
+ });
346
+ // Phase 11: Send message and stream events
347
+ status.phase = ExecutionPhase.EXECUTION_IN_PROGRESS;
348
+ const deltaEnricher = new DeltaEnricher();
349
+ const todoTracker = new TodoTracker(status.todos);
350
+ const eventRecorder = createCursorEventRecorder(executionId);
351
+ let platformStopSignaled = false;
352
+ let firstTurnAttributionLogged = false;
353
+ let streamErrorMessage;
354
+ let alreadyRetriedWithFreshAgent = false;
355
+ // Periodic heartbeat keeps Temporal informed during silent SDK operations
356
+ // (e.g. long tool calls, MCP requests, model thinking). Without this,
357
+ // the 2-minute heartbeat timeout can cancel the activity and mislabel
358
+ // the execution as "paused by user".
359
+ const taskQueue = Context.current().info.taskQueue;
360
+ const shutdownSignal = getShutdownSignalForQueue(taskQueue);
361
+ periodicHeartbeat = startHeartbeat(30_000, () => ({
362
+ phase: "cursor_streaming",
363
+ execution: executionId,
364
+ }), { shutdownSignal });
365
+ // The Cursor SDK registers abort listeners on the cancellation signal for
366
+ // each concurrent tool call (fetch, MCP, shell). With 10+ parallel tools,
367
+ // Node's default limit of 10 triggers MaxListenersExceededWarning. This is
368
+ // a diagnostic warning, not a functional error — reproduction tests confirm
369
+ // zero tool call loss — but it pollutes logs and creates false alarm fatigue.
370
+ // Raise the limit on the Temporal cancellation signal used throughout this
371
+ // activity. 25 covers observed peaks (~12 concurrent tools + heartbeat +
372
+ // shutdown signal + SDK internals) with headroom.
373
+ try {
374
+ setMaxListeners(25, Context.current().cancellationSignal);
375
+ }
376
+ catch {
377
+ // Fallback: if the Temporal signal doesn't support setMaxListeners
378
+ // (e.g. older SDK), the warning is harmless — ignore.
379
+ }
380
+ const run = await resolution.agent.send(effectivePrompt, {
381
+ onDelta: ({ update }) => {
382
+ if (update.type === "turn-ended" && update.usage) {
383
+ usageAccumulator.addTurn(update.usage);
384
+ if (!firstTurnAttributionLogged) {
385
+ firstTurnAttributionLogged = true;
386
+ const sdkInputTokens = update.usage.inputTokens ?? 0;
387
+ const cursorOverhead = Math.max(0, sdkInputTokens - promptEstimatedTokens);
388
+ console.log(`ExecuteCursor context attribution (first turn): execution=${executionId}, ` +
389
+ `sdkInputTokens=${sdkInputTokens}, stigmerPreamble=${promptEstimatedTokens}, ` +
390
+ `cursorOverhead=${cursorOverhead} (estimated)`);
391
+ }
392
+ }
393
+ deltaEnricher.processDelta(update);
394
+ try {
395
+ heartbeat();
396
+ }
397
+ catch (hbErr) {
398
+ if (hbErr instanceof CancelledFailure) {
399
+ pauseDetected = true;
400
+ return;
401
+ }
402
+ throw hbErr;
403
+ }
404
+ },
405
+ });
406
+ const accumulator = new MessageAccumulator(status.messages, { mergedPolicies });
407
+ let eventCount = 0;
408
+ for await (const event of run.stream()) {
409
+ if (pauseDetected || Context.current().cancellationSignal.aborted) {
410
+ pauseDetected = true;
411
+ break;
412
+ }
413
+ eventRecorder?.record(event, eventCount);
414
+ accumulator.processEvent(event);
415
+ todoTracker.processEvent(event);
416
+ if (event.type === "tool_call" && event.name === "task") {
417
+ accumulator.trackSubAgentExecution(event);
418
+ }
419
+ deltaEnricher.applyEnrichments(status.messages);
420
+ eventCount++;
421
+ if (event.type === "status") {
422
+ console.log(`ExecuteCursor stream status: execution=${executionId}, status=${JSON.stringify(event)}`);
423
+ const statusEvent = event;
424
+ if (statusEvent.status === "ERROR" && statusEvent.message) {
425
+ streamErrorMessage = statusEvent.message;
426
+ }
427
+ }
428
+ const shouldPersist = eventCount % 20 === 0 || deltaEnricher.isDirty ||
429
+ todoTracker.isDirty || accumulator.subAgentDirty;
430
+ if (usageAccumulator.hasTurns) {
431
+ status.streamingUsage = create(StreamingUsageSummarySchema, usageAccumulator.snapshot());
432
+ }
433
+ if (shouldPersist) {
434
+ // Sync sub-agent executions into status before every persist so the
435
+ // live UI reflects delegation (including the IN_PROGRESS state) while
436
+ // the parent is still running — matching the native harness, which
437
+ // calls syncSubAgentExecutions() on each persist. Without this, the
438
+ // accumulator tracked sub-agents in memory but they only reached the
439
+ // status (and the subscriber stream) after the loop ended.
440
+ status.subAgentExecutions = accumulator.subAgentExecutions;
441
+ const signal = await persistStatus(client, executionId, status);
442
+ deltaEnricher.markPersisted();
443
+ todoTracker.markPersisted();
444
+ accumulator.markSubAgentPersisted();
445
+ heartbeat();
446
+ if (signal === ExecutionControlSignal.STOP) {
447
+ platformStopSignaled = true;
448
+ console.warn(`ExecuteCursor platform stop signal received: execution=${executionId}`);
449
+ }
450
+ }
451
+ if (platformStopSignaled) {
452
+ console.log(`ExecuteCursor stopping stream due to platform stop signal: execution=${executionId}`);
453
+ break;
454
+ }
455
+ }
456
+ periodicHeartbeat.stop();
457
+ // Check both the heartbeat flag AND the shutdown signal directly.
458
+ // Race condition: the heartbeat timer may detect Temporal's CancelledFailure
459
+ // (from worker.shutdown()) before the AbortSignal microtask propagates,
460
+ // causing it to set `cancelled` instead of `workerShutdown`. The direct
461
+ // signal check catches this case.
462
+ const isShutdown = periodicHeartbeat.workerShutdown || (shutdownSignal?.aborted ?? false);
463
+ if (isShutdown) {
464
+ pauseDetected = false;
465
+ }
466
+ else if (periodicHeartbeat.cancelled) {
467
+ pauseDetected = true;
468
+ }
469
+ workerShutdownDetected = isShutdown;
470
+ accumulator.finalize();
471
+ deltaEnricher.finalize(status.messages);
472
+ // A pause / cancel / worker shutdown aborts the Cursor SDK run, so any
473
+ // sub-agent the parent had delegated is no longer executing. Mark it
474
+ // CANCELLED rather than leaving a permanent IN_PROGRESS "zombie" in the
475
+ // final snapshot (parity with the native harness's cancelSubAgents()).
476
+ if (pauseDetected || workerShutdownDetected || Context.current().cancellationSignal.aborted) {
477
+ accumulator.cancelInProgressSubAgents();
478
+ }
479
+ status.subAgentExecutions = accumulator.subAgentExecutions;
480
+ await eventRecorder?.flush();
481
+ if (usageAccumulator.hasTurns) {
482
+ status.streamingUsage = create(StreamingUsageSummarySchema, usageAccumulator.snapshot());
483
+ }
484
+ console.log(`ExecuteCursor stream ended: execution=${executionId}, events=${eventCount}, messages=${status.messages.length}, subAgents=${status.subAgentExecutions.length}`);
485
+ // Persist immediately after finalize so the UI sees correct tool
486
+ // call statuses before run.wait() / structured output extraction.
487
+ // This is unconditional (not throttled) because finalize is a
488
+ // once-per-execution correctness boundary.
489
+ await persistStatus(client, executionId, status);
490
+ heartbeat();
491
+ // End OTel turn span with accumulated token usage
492
+ const usageSnapshot = usageAccumulator.snapshot();
493
+ turnSpan.setTokens(Number(usageSnapshot.inputTokens), Number(usageSnapshot.outputTokens));
494
+ turnSpan.end();
495
+ // Record cursor turn metrics (duration, tokens)
496
+ try {
497
+ const { recordTurnMetrics } = await import("../../otel.js");
498
+ const turnDurationMs = Date.now() - (status.startedAt ? new Date(status.startedAt).getTime() : Date.now());
499
+ await recordTurnMetrics({
500
+ durationMs: turnDurationMs,
501
+ inputTokens: Number(usageSnapshot.inputTokens),
502
+ outputTokens: Number(usageSnapshot.outputTokens),
503
+ model: validatedModel,
504
+ mode: agentMode,
505
+ });
506
+ }
507
+ catch {
508
+ // Metrics not initialized — silently skip.
509
+ }
510
+ // Phase 11a: Handle worker shutdown, pause, or infrastructure cancellation.
511
+ // Worker shutdown: the runner-manager aborted the shutdown signal before
512
+ // calling worker.shutdown(). This is NOT a user-initiated pause — it's
513
+ // an infrastructure event (e.g., premature removal from UI race).
514
+ if (workerShutdownDetected) {
515
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
516
+ status.error = "Execution interrupted: runner worker was shut down. Retry or resume.";
517
+ status.completedAt = utcTimestamp();
518
+ status.messages.push(create(AgentMessageSchema, {
519
+ type: MessageType.MESSAGE_SYSTEM,
520
+ content: "Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
521
+ timestamp: utcTimestamp(),
522
+ }));
523
+ await persistStatus(client, executionId, status);
524
+ console.log(`ExecuteCursor interrupted (worker shutdown): execution=${executionId}, events=${eventCount}`);
525
+ throw new CancelledFailure("Activity cancelled (worker shutdown, not user pause)");
526
+ }
527
+ // pauseDetected is only true if a heartbeat() call threw CancelledFailure,
528
+ // confirming the orchestrator explicitly requested a pause.
529
+ if (pauseDetected) {
530
+ status.phase = ExecutionPhase.EXECUTION_PAUSED;
531
+ status.messages.push(create(AgentMessageSchema, {
532
+ type: MessageType.MESSAGE_SYSTEM,
533
+ content: "Execution paused by user. Use resume to continue.",
534
+ timestamp: utcTimestamp(),
535
+ }));
536
+ await persistStatus(client, executionId, status);
537
+ console.log(`ExecuteCursor paused: execution=${executionId}, events=${eventCount}`);
538
+ throw new CancelledFailure("Activity paused by orchestrator");
539
+ }
540
+ // If cancellation arrived without pauseDetected (e.g. heartbeat timeout
541
+ // that slipped past the periodic heartbeat, or worker shutdown), report
542
+ // as failed rather than misleadingly labeling it as user-paused.
543
+ if (Context.current().cancellationSignal.aborted) {
544
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
545
+ status.error = "Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.";
546
+ status.completedAt = utcTimestamp();
547
+ status.messages.push(create(AgentMessageSchema, {
548
+ type: MessageType.MESSAGE_SYSTEM,
549
+ content: "Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",
550
+ timestamp: utcTimestamp(),
551
+ }));
552
+ await persistStatus(client, executionId, status);
553
+ console.log(`ExecuteCursor interrupted (infrastructure cancel): execution=${executionId}, events=${eventCount}`);
554
+ throw new CancelledFailure("Activity cancelled (heartbeat timeout, not user pause)");
555
+ }
556
+ // Phase 11b: Handle platform stop signal early exit
557
+ if (platformStopSignaled) {
558
+ status.phase = ExecutionPhase.EXECUTION_COMPLETED;
559
+ status.completedAt = utcTimestamp();
560
+ status.messages.push(create(AgentMessageSchema, {
561
+ type: MessageType.MESSAGE_SYSTEM,
562
+ content: "Execution stopped by the platform.",
563
+ timestamp: utcTimestamp(),
564
+ }));
565
+ await persistStatus(client, executionId, status);
566
+ try {
567
+ resolution.agent.close();
568
+ }
569
+ catch { /* best effort */ }
570
+ console.log(`ExecuteCursor completed (platform stop): execution=${executionId}`);
571
+ return slimStatus(status);
572
+ }
573
+ // Phase 12: Surface tools the preToolUse hook gated (HITL).
574
+ //
575
+ // The hook records each denial to the ledger; we mark the corresponding tool
576
+ // calls WAITING_APPROVAL. The backend projects pending_approvals from that
577
+ // tool-call status (PendingApprovalComputer), so — exactly like the native
578
+ // harness — the approval surface is driven entirely by tool-call status. We
579
+ // deliberately do NOT set status.pendingApprovals here: any value would be
580
+ // discarded by the backend's recompute on the next updateStatus.
581
+ const deniedLedger = await readDenialLedger(primaryWorkspaceDir);
582
+ const deniedToolCalls = reconcileDeniedToolCalls(status.messages, deniedLedger, mergedPolicies);
583
+ if (deniedToolCalls.length > 0) {
584
+ status.phase = ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL;
585
+ await persistStatus(client, executionId, status);
586
+ console.log(`ExecuteCursor returning WAITING_FOR_APPROVAL: ${deniedToolCalls.length} tools pending`);
587
+ return slimStatus(status);
588
+ }
589
+ // Phase 13: Map final result
590
+ const result = await run.wait();
591
+ const sdkResolvedModel = result.model?.id || undefined;
592
+ console.log(`ExecuteCursor run.wait() result: execution=${executionId}, result=${JSON.stringify(result)}`);
593
+ if (sdkResolvedModel && sdkResolvedModel !== validatedModel) {
594
+ console.log(`ExecuteCursor model divergence: execution=${executionId}, requested=${validatedModel}, sdkResolved=${sdkResolvedModel}`);
595
+ }
596
+ status.completedAt = utcTimestamp();
597
+ switch (result.status) {
598
+ case "finished":
599
+ status.phase = ExecutionPhase.EXECUTION_COMPLETED;
600
+ break;
601
+ case "error": {
602
+ const resultAny = result;
603
+ const sdkError = result.result
604
+ ?? resultAny.error
605
+ ?? resultAny.message
606
+ ?? resultAny.reason;
607
+ const sdkErrorStr = sdkError ? String(sdkError) : undefined;
608
+ // The SDK frequently resolves run.wait() to a bare { status: "error" }
609
+ // while the real reason (e.g. the original grpc-status 12 routing
610
+ // failure) lives on the failing conversation turn. Capture it here so
611
+ // the classified error is actionable instead of "no detail from SDK".
612
+ const conversationErrorText = await introspectConversation(run, executionId);
613
+ const capturedRejection = getCapturedRejection(executionId);
614
+ if (capturedRejection)
615
+ clearCapturedRejection(executionId);
616
+ const classified = synthesizeError({
617
+ sdkResultFields: sdkErrorStr,
618
+ streamErrorMessage,
619
+ capturedRejection,
620
+ conversationErrorText,
621
+ isResumedHandle: resolution.reason === "resumed_successfully",
622
+ fallbackContext: { model: validatedModel, mode: agentMode, agentId: resolution.agentId },
623
+ durationMs: result.durationMs,
624
+ messageCount: status.messages.length,
625
+ });
626
+ console.error(`ExecuteCursor agent error: execution=${executionId}, ` +
627
+ `classified=${JSON.stringify(classified)}, rawResult=${JSON.stringify(result)}`);
628
+ if (shouldRetryWithFreshAgent(classified)
629
+ && resolution.reason === "resumed_successfully"
630
+ && !alreadyRetriedWithFreshAgent) {
631
+ alreadyRetriedWithFreshAgent = true;
632
+ console.warn(`ExecuteCursor poisoned-handle recovery: execution=${executionId}, ` +
633
+ `disposing agent ${resolution.agentId} and creating fresh agent`);
634
+ try {
635
+ resolution.agent.close();
636
+ }
637
+ catch { /* best effort */ }
638
+ const freshAgent = agentMode === "cloud"
639
+ ? await createCloudAgent(createOptions)
640
+ : await createAgent(createOptions);
641
+ const freshPrompt = buildPrompt({
642
+ resolution: {
643
+ ...resolution,
644
+ agent: freshAgent,
645
+ agentId: freshAgent.agentId,
646
+ isNew: true,
647
+ resumed: false,
648
+ reason: "created_after_resume_failure",
649
+ resumeFailureDetail: `poisoned-handle recovery: ${classified.message}`,
650
+ },
651
+ approvalDecisions,
652
+ instructions: blueprint.instructions,
653
+ userMessage: spec.message,
654
+ skills: skillMetadata,
655
+ subAgents: blueprint.subAgents,
656
+ workspaceDirs: blueprint.workspaceDirs,
657
+ workspaceFileRefs: spec.workspaceFileRefs ?? [],
658
+ attachmentPaths,
659
+ pendingApprovals: adjudicatedApprovals,
660
+ interactionMode,
661
+ });
662
+ console.log(`ExecuteCursor retry with fresh agent: execution=${executionId}, ` +
663
+ `newAgentId=${freshAgent.agentId}`);
664
+ try {
665
+ blueprint.sessionSpec.harnessStateId = freshAgent.agentId;
666
+ if (blueprint.session.metadata)
667
+ blueprint.session.metadata.slug = "";
668
+ await client.updateSession(blueprint.session);
669
+ }
670
+ catch (updateErr) {
671
+ console.warn("Failed to update session with fresh agentId (non-fatal):", updateErr);
672
+ }
673
+ const retryRun = await freshAgent.send(freshPrompt, {
674
+ onDelta: ({ update }) => {
675
+ if (update.type === "turn-ended" && update.usage) {
676
+ usageAccumulator.addTurn(update.usage);
677
+ }
678
+ deltaEnricher.processDelta(update);
679
+ try {
680
+ heartbeat();
681
+ }
682
+ catch { /* swallow during retry */ }
683
+ },
684
+ });
685
+ streamErrorMessage = undefined;
686
+ for await (const retryEvent of retryRun.stream()) {
687
+ if (Context.current().cancellationSignal.aborted)
688
+ break;
689
+ accumulator.processEvent(retryEvent);
690
+ if (retryEvent.type === "status") {
691
+ const retryStatusEvent = retryEvent;
692
+ if (retryStatusEvent.status === "ERROR" && retryStatusEvent.message) {
693
+ streamErrorMessage = retryStatusEvent.message;
694
+ }
695
+ }
696
+ heartbeat();
697
+ }
698
+ const retryResult = await retryRun.wait();
699
+ console.log(`ExecuteCursor retry run.wait(): execution=${executionId}, ` +
700
+ `retryResult=${JSON.stringify(retryResult)}`);
701
+ if (retryResult.status === "finished") {
702
+ status.phase = ExecutionPhase.EXECUTION_COMPLETED;
703
+ console.log(`ExecuteCursor poisoned-handle recovery SUCCEEDED: execution=${executionId}`);
704
+ break;
705
+ }
706
+ if (retryResult.status === "cancelled") {
707
+ status.phase = ExecutionPhase.EXECUTION_CANCELLED;
708
+ break;
709
+ }
710
+ const retryRejection = getCapturedRejection(executionId);
711
+ if (retryRejection)
712
+ clearCapturedRejection(executionId);
713
+ const retryConversationErrorText = await introspectConversation(retryRun, executionId);
714
+ const retryClassified = synthesizeError({
715
+ sdkResultFields: retryResult.result ? String(retryResult.result) : undefined,
716
+ streamErrorMessage,
717
+ capturedRejection: retryRejection,
718
+ conversationErrorText: retryConversationErrorText,
719
+ isResumedHandle: false,
720
+ fallbackContext: { model: validatedModel, mode: agentMode, agentId: freshAgent.agentId },
721
+ });
722
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
723
+ status.error = formatClassifiedError(retryClassified);
724
+ console.error(`ExecuteCursor poisoned-handle recovery FAILED: execution=${executionId}, ` +
725
+ `retryError=${status.error}`);
726
+ break;
727
+ }
728
+ // Transport-timeout retry: fresh agent got 0 messages (degraded h2 session).
729
+ // Reset proxy sessions and try once with a new connection.
730
+ if (classified.category === "network"
731
+ && classified.retryable
732
+ && resolution.reason !== "resumed_successfully"
733
+ && !alreadyRetriedWithFreshAgent) {
734
+ alreadyRetriedWithFreshAgent = true;
735
+ console.warn(`ExecuteCursor transport-timeout recovery: execution=${executionId}, ` +
736
+ `resetting proxy sessions and retrying with fresh agent`);
737
+ try {
738
+ resolution.agent.close();
739
+ }
740
+ catch { /* best effort */ }
741
+ closeProxySessions();
742
+ const freshAgent = agentMode === "cloud"
743
+ ? await createCloudAgent(createOptions)
744
+ : await createAgent(createOptions);
745
+ try {
746
+ blueprint.sessionSpec.harnessStateId = freshAgent.agentId;
747
+ if (blueprint.session.metadata)
748
+ blueprint.session.metadata.slug = "";
749
+ await client.updateSession(blueprint.session);
750
+ }
751
+ catch (updateErr) {
752
+ console.warn("Failed to update session with fresh agentId (non-fatal):", updateErr);
753
+ }
754
+ const retryRun = await freshAgent.send(effectivePrompt, {
755
+ onDelta: ({ update }) => {
756
+ if (update.type === "turn-ended" && update.usage) {
757
+ usageAccumulator.addTurn(update.usage);
758
+ }
759
+ deltaEnricher.processDelta(update);
760
+ try {
761
+ heartbeat();
762
+ }
763
+ catch { /* swallow during retry */ }
764
+ },
765
+ });
766
+ streamErrorMessage = undefined;
767
+ for await (const retryEvent of retryRun.stream()) {
768
+ if (Context.current().cancellationSignal.aborted)
769
+ break;
770
+ accumulator.processEvent(retryEvent);
771
+ if (retryEvent.type === "status") {
772
+ const retryStatusEvent = retryEvent;
773
+ if (retryStatusEvent.status === "ERROR" && retryStatusEvent.message) {
774
+ streamErrorMessage = retryStatusEvent.message;
775
+ }
776
+ }
777
+ heartbeat();
778
+ }
779
+ const retryResult = await retryRun.wait();
780
+ if (retryResult.status === "finished") {
781
+ status.phase = ExecutionPhase.EXECUTION_COMPLETED;
782
+ resolution = { ...resolution, agent: freshAgent, agentId: freshAgent.agentId, isNew: true };
783
+ break;
784
+ }
785
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
786
+ status.error = `Transport recovery failed: ${formatClassifiedError(classified)}`;
787
+ break;
788
+ }
789
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
790
+ status.error = formatClassifiedError(classified);
791
+ break;
792
+ }
793
+ case "cancelled":
794
+ status.phase = ExecutionPhase.EXECUTION_CANCELLED;
795
+ break;
796
+ default:
797
+ status.phase = ExecutionPhase.EXECUTION_COMPLETED;
798
+ }
799
+ // Extract structured output BEFORE persisting, so the subscriber sees
800
+ // COMPLETED + structured_output atomically.
801
+ let structuredOutput = undefined;
802
+ let finalText;
803
+ if (status.phase === ExecutionPhase.EXECUTION_COMPLETED) {
804
+ const lastAiMsg = [...status.messages]
805
+ .reverse()
806
+ .find(m => m.type === MessageType.MESSAGE_AI);
807
+ finalText = lastAiMsg?.content;
808
+ if (structuredOutputSchema && finalText) {
809
+ const { extractJsonFromText } = await import("../../shared/extract-json.js");
810
+ // Tier 1 + 1.5: JSON.parse, code-fence extraction, heuristic brace match
811
+ structuredOutput = extractJsonFromText(finalText);
812
+ if (structuredOutput !== undefined) {
813
+ console.log(`ExecuteCursor structured output extracted (text): execution=${executionId}, ` +
814
+ `finalTextLength=${finalText.length}`);
815
+ }
816
+ if (structuredOutput === undefined) {
817
+ // Tier 2: LLM extraction with withStructuredOutput — deterministic,
818
+ // uses function-calling to guarantee schema-conformant output
819
+ console.log(`ExecuteCursor text extraction failed, trying LLM extraction: execution=${executionId}, ` +
820
+ `finalTextLength=${finalText.length}`);
821
+ try {
822
+ structuredOutput = await extractStructuredOutput(finalText, structuredOutputSchema, config, requestedModel);
823
+ if (structuredOutput !== undefined) {
824
+ console.log(`ExecuteCursor structured output extracted (LLM): execution=${executionId}`);
825
+ }
826
+ }
827
+ catch (extractErr) {
828
+ const errMsg = extractErr instanceof Error ? extractErr.message : String(extractErr);
829
+ console.error(`ExecuteCursor structured output extraction FAILED: execution=${executionId}, ` +
830
+ `requestedModel=${requestedModel}, ` +
831
+ `finalTextLength=${finalText.length}, ` +
832
+ `error=${errMsg}`);
833
+ }
834
+ }
835
+ }
836
+ if (structuredOutput !== undefined) {
837
+ status.structuredOutput = structuredOutput;
838
+ }
839
+ // Plan mode: publish the final plan message as a plan.md artifact. The
840
+ // Cursor harness has no auto-publish pipeline, so this is the only
841
+ // artifact path; build storage from the same config-driven factory the
842
+ // native harness uses.
843
+ if (interactionMode === InteractionMode.PLAN && finalText) {
844
+ try {
845
+ const artifactStorage = createArtifactStorage(loadArtifactStorageConfig(config));
846
+ await publishPlanArtifact({ status, executionId, planText: finalText, artifactStorage });
847
+ }
848
+ catch (err) {
849
+ console.warn(`ExecuteCursor plan artifact publish skipped (non-fatal): ` +
850
+ `execution=${executionId}, error=${err}`);
851
+ }
852
+ }
853
+ }
854
+ // NOW persist — subscriber sees COMPLETED + structured_output atomically
855
+ await persistStatus(client, executionId, status);
856
+ console.log(`ExecuteCursor completed: execution=${executionId}, phase=${ExecutionPhase[status.phase]}, ` +
857
+ `hasStructuredOutput=${structuredOutput !== undefined}` +
858
+ (status.error ? `, error=${status.error}` : ""));
859
+ // Release SDK executor lease to prevent cache buildup across workflow tasks
860
+ try {
861
+ resolution.agent.close();
862
+ }
863
+ catch { /* best effort */ }
864
+ const slim = slimStatus(status);
865
+ if (finalText !== undefined) {
866
+ slim.final_text = finalText;
867
+ }
868
+ if (structuredOutput !== undefined) {
869
+ slim.structured = structuredOutput;
870
+ }
871
+ return slim;
872
+ }
873
+ catch (err) {
874
+ periodicHeartbeat?.stop();
875
+ if (err instanceof CancelledFailure) {
876
+ // workerShutdownDetected means the runner-manager signaled shutdown
877
+ // before the worker drained. This is infrastructure failure, not pause.
878
+ if (workerShutdownDetected) {
879
+ console.log(`ExecuteCursor cancelled (worker shutdown) for execution ${executionId}`);
880
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
881
+ status.error = "Execution interrupted: runner worker was shut down. Retry or resume.";
882
+ status.completedAt = utcTimestamp();
883
+ status.messages.push(create(AgentMessageSchema, {
884
+ type: MessageType.MESSAGE_SYSTEM,
885
+ content: "Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",
886
+ timestamp: utcTimestamp(),
887
+ }));
888
+ }
889
+ else if (pauseDetected) {
890
+ console.log(`ExecuteCursor cancelled (pause) for execution ${executionId}`);
891
+ status.phase = ExecutionPhase.EXECUTION_PAUSED;
892
+ status.messages.push(create(AgentMessageSchema, {
893
+ type: MessageType.MESSAGE_SYSTEM,
894
+ content: "Execution paused by user. Use resume to continue.",
895
+ timestamp: utcTimestamp(),
896
+ }));
897
+ }
898
+ else {
899
+ console.log(`ExecuteCursor cancelled (infrastructure) for execution ${executionId}`);
900
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
901
+ status.error = "Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.";
902
+ status.completedAt = utcTimestamp();
903
+ status.messages.push(create(AgentMessageSchema, {
904
+ type: MessageType.MESSAGE_SYSTEM,
905
+ content: "Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",
906
+ timestamp: utcTimestamp(),
907
+ }));
908
+ }
909
+ // The aborted Cursor run leaves no live sub-agent — mark any in-flight
910
+ // delegation CANCELLED so the final snapshot has no zombie sub-agent.
911
+ cancelInProgressSubAgentProtos(status.subAgentExecutions);
912
+ await persistStatus(client, executionId, status).catch(() => { });
913
+ throw err;
914
+ }
915
+ // If a non-CancelledFailure error occurs while a pause is in progress,
916
+ // treat the execution as paused rather than failed. The error was likely
917
+ // caused by the cancellation (e.g. SDK stream teardown) and should not
918
+ // overwrite the PAUSED state that the Pause RPC already set in the DB.
919
+ if (pauseDetected) {
920
+ const errDetail = err instanceof Error ? err.message : String(err);
921
+ console.log(`ExecuteCursor error during pause (treating as pause): execution=${executionId}, error=${errDetail}`);
922
+ status.phase = ExecutionPhase.EXECUTION_PAUSED;
923
+ status.messages.push(create(AgentMessageSchema, {
924
+ type: MessageType.MESSAGE_SYSTEM,
925
+ content: "Execution paused by user. Use resume to continue.",
926
+ timestamp: utcTimestamp(),
927
+ }));
928
+ cancelInProgressSubAgentProtos(status.subAgentExecutions);
929
+ await persistStatus(client, executionId, status).catch(() => { });
930
+ throw new CancelledFailure("Activity paused by orchestrator (error during pause)");
931
+ }
932
+ // Infrastructure cancellation (e.g. heartbeat timeout) with a
933
+ // non-CancelledFailure error — report as failed, not paused.
934
+ if (Context.current().cancellationSignal.aborted) {
935
+ const errDetail = err instanceof Error ? err.message : String(err);
936
+ console.log(`ExecuteCursor error during infrastructure cancel: execution=${executionId}, error=${errDetail}`);
937
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
938
+ status.error = `Execution interrupted: ${errDetail}`;
939
+ status.completedAt = utcTimestamp();
940
+ status.messages.push(create(AgentMessageSchema, {
941
+ type: MessageType.MESSAGE_SYSTEM,
942
+ content: "Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",
943
+ timestamp: utcTimestamp(),
944
+ }));
945
+ cancelInProgressSubAgentProtos(status.subAgentExecutions);
946
+ await persistStatus(client, executionId, status).catch(() => { });
947
+ throw new CancelledFailure("Activity cancelled (infrastructure, not user pause)");
948
+ }
949
+ // A thrown CursorSdkError carries structured fields (code/status/endpoint/
950
+ // requestId) that the generic format below would flatten to a bare message.
951
+ // Route it through the same classifier as the run.wait() error path so the
952
+ // failure category and full diagnostics are preserved.
953
+ const { CursorSdkError } = await import("@cursor/sdk");
954
+ if (err instanceof CursorSdkError) {
955
+ const sdkErrorJson = err.toJSON();
956
+ console.error(`ExecuteCursor SDK error: execution=${executionId}, sdkError=${JSON.stringify(sdkErrorJson)}`);
957
+ const classified = synthesizeError({
958
+ sdkError: { code: err.code, status: err.status, message: err.message },
959
+ sdkResultFields: undefined,
960
+ streamErrorMessage: undefined,
961
+ capturedRejection: getCapturedRejection(executionId),
962
+ isResumedHandle: false,
963
+ fallbackContext: errorContext,
964
+ });
965
+ clearCapturedRejection(executionId);
966
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
967
+ status.error = formatClassifiedError(classified);
968
+ status.completedAt = utcTimestamp();
969
+ status.messages.push(create(AgentMessageSchema, {
970
+ type: MessageType.MESSAGE_SYSTEM,
971
+ content: "Internal system error occurred. Please contact support if this issue persists.",
972
+ timestamp: utcTimestamp(),
973
+ }), create(AgentMessageSchema, {
974
+ type: MessageType.MESSAGE_SYSTEM,
975
+ content: `Error details: ${status.error}`,
976
+ timestamp: utcTimestamp(),
977
+ }));
978
+ try {
979
+ await persistStatus(client, executionId, status);
980
+ }
981
+ catch (persistErr) {
982
+ console.error("Failed to persist error status (best-effort):", persistErr);
983
+ }
984
+ return slimStatus(status);
985
+ }
986
+ const errMsg = err instanceof Error ? err.message : String(err);
987
+ const errType = err instanceof Error ? err.constructor.name : "Unknown";
988
+ console.error(`ExecuteCursor failed: execution=${executionId}, [${errType}] ${errMsg}`);
989
+ status.phase = ExecutionPhase.EXECUTION_FAILED;
990
+ status.error = `Execution failed: [${errType}] ${errMsg}`;
991
+ status.completedAt = utcTimestamp();
992
+ status.messages.push(create(AgentMessageSchema, {
993
+ type: MessageType.MESSAGE_SYSTEM,
994
+ content: "Internal system error occurred. Please contact support if this issue persists.",
995
+ timestamp: utcTimestamp(),
996
+ }), create(AgentMessageSchema, {
997
+ type: MessageType.MESSAGE_SYSTEM,
998
+ content: `Error details: [${errType}] ${errMsg}`,
999
+ timestamp: utcTimestamp(),
1000
+ }));
1001
+ try {
1002
+ await persistStatus(client, executionId, status);
1003
+ }
1004
+ catch (persistErr) {
1005
+ console.error("Failed to persist error status (best-effort):", persistErr);
1006
+ }
1007
+ return slimStatus(status);
1008
+ }
1009
+ }
1010
+ // ---------------------------------------------------------------------------
1011
+ // Structured Output Extraction (Cursor Harness Tier 2)
1012
+ // ---------------------------------------------------------------------------
1013
+ /**
1014
+ * Extract structured data from an agent's free-text response using an
1015
+ * economy-tier LLM with withStructuredOutput (function-calling).
1016
+ * Guarantees schema-conformant JSON output via the API's tool-use mechanism.
1017
+ *
1018
+ * Provider-aware: resolves the economy model via the registry, infers its
1019
+ * provider (anthropic / openai), and constructs the correct LangChain client
1020
+ * with the matching proxy endpoint. Follows the same pattern as
1021
+ * call-llm.ts constructModel().
1022
+ */
1023
+ async function extractStructuredOutput(agentResponse, schema, config, primaryModel) {
1024
+ const { ChatOpenAI } = await import("@langchain/openai");
1025
+ const { ChatAnthropic } = await import("@langchain/anthropic");
1026
+ const { inferProvider, resolveProxyBaseUrl, buildProxyHeaders } = await import("../../shared/llm-proxy.js");
1027
+ const { getEconomyModel } = await import("../../shared/model-registry.js");
1028
+ const extractionModel = await getEconomyModel(primaryModel);
1029
+ const provider = inferProvider(extractionModel);
1030
+ const proxyEndpoint = config.proxyEndpoint ?? config.stigmerBackendEndpoint;
1031
+ const baseUrl = resolveProxyBaseUrl(proxyEndpoint, provider);
1032
+ const headers = config.stigmerToken
1033
+ ? buildProxyHeaders(config.stigmerToken, {})
1034
+ : {};
1035
+ const apiKey = provider === "openai"
1036
+ ? (config.stigmerToken ?? process.env.OPENAI_API_KEY ?? "proxy-managed")
1037
+ : (config.stigmerToken ?? process.env.ANTHROPIC_API_KEY ?? "proxy-managed");
1038
+ const llm = provider === "openai"
1039
+ ? new ChatOpenAI({
1040
+ model: extractionModel,
1041
+ apiKey,
1042
+ temperature: 0,
1043
+ maxTokens: 4096,
1044
+ configuration: { baseURL: baseUrl, defaultHeaders: headers },
1045
+ })
1046
+ : new ChatAnthropic({
1047
+ model: extractionModel,
1048
+ apiKey,
1049
+ temperature: 0,
1050
+ maxTokens: 4096,
1051
+ clientOptions: { baseURL: baseUrl, defaultHeaders: headers },
1052
+ });
1053
+ const zodSchema = jsonSchemaToZod(schema);
1054
+ const structured = llm.withStructuredOutput(zodSchema);
1055
+ const result = await structured.invoke([
1056
+ { role: "system", content: "Extract the structured data from the agent's response. Return only the data that matches the schema." },
1057
+ { role: "user", content: agentResponse },
1058
+ ]);
1059
+ return result ?? null;
1060
+ }
1061
+ // Re-export for use within this module; shared implementation eliminates
1062
+ // the three duplicate converters that previously drifted independently.
1063
+ import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
1064
+ /**
1065
+ * Select and build the appropriate prompt based on resolution reason and
1066
+ * HITL state.
1067
+ *
1068
+ * Conversation continuation is carried entirely by the Cursor SDK's native
1069
+ * agent state (the local SQLite store persisted on the durable workspace
1070
+ * volume, or cloud server-side state) — there is no separate continuation
1071
+ * store. The prompt therefore depends only on how the agent was resolved:
1072
+ *
1073
+ * 1. HITL reinvocation -> buildReinvocationPrompt (approval decisions;
1074
+ * the resumed agent's native context carries
1075
+ * the prior conversation)
1076
+ * 2. resumed_successfully -> raw userMessage (native context carries it)
1077
+ * 3. first execution / fresh -> buildEnhancedPrompt (full instructions +
1078
+ * agent after resume failure skills; no prior conversation to inherit)
1079
+ */
1080
+ export function buildPrompt(input) {
1081
+ const { resolution, approvalDecisions, instructions, userMessage, skills, subAgents, workspaceDirs, workspaceFileRefs, attachmentPaths, interactionMode, } = input;
1082
+ const isHitlReinvocation = approvalDecisions !== undefined && approvalDecisions.size > 0;
1083
+ // HITL reinvocation: the agent is resumed, so its native context carries the
1084
+ // prior conversation; the reinvocation prompt conveys the approval decisions.
1085
+ if (isHitlReinvocation) {
1086
+ return buildReinvocationPrompt(input.pendingApprovals, approvalDecisions);
1087
+ }
1088
+ // A successfully resumed agent carries its own conversation context via the
1089
+ // SDK's native store — send the raw user message with no preamble.
1090
+ if (resolution.reason === "resumed_successfully") {
1091
+ return userMessage;
1092
+ }
1093
+ // First execution, or a fresh agent created after a resume failure: there is
1094
+ // no prior conversation to inherit, so start a new turn with full context.
1095
+ return buildEnhancedPrompt({
1096
+ instructions,
1097
+ userMessage,
1098
+ skills,
1099
+ subAgents,
1100
+ workspaceDirs,
1101
+ workspaceFileRefs,
1102
+ attachmentPaths,
1103
+ interactionMode,
1104
+ });
1105
+ }
1106
+ // ---------------------------------------------------------------------------
1107
+ // Helpers
1108
+ // ---------------------------------------------------------------------------
1109
+ /**
1110
+ * Best-effort: read the failing run's conversation to recover the real error
1111
+ * reason the SDK swallowed in run.wait(). Logs the (bounded) raw turns for deep
1112
+ * diagnostics and returns a concise error string for the classifier.
1113
+ *
1114
+ * Strictly non-fatal — any failure (unsupported operation, transport error)
1115
+ * returns undefined and never propagates into the execution's error path.
1116
+ */
1117
+ async function introspectConversation(run, executionId) {
1118
+ try {
1119
+ if (!run.supports("conversation")) {
1120
+ console.log(`ExecuteCursor conversation introspection unsupported: execution=${executionId}, ` +
1121
+ `reason=${run.unsupportedReason("conversation") ?? "n/a"}`);
1122
+ return undefined;
1123
+ }
1124
+ const turns = await run.conversation();
1125
+ const raw = JSON.stringify(turns);
1126
+ const bounded = raw.length > 8000 ? `${raw.slice(0, 8000)}…(truncated ${raw.length} chars)` : raw;
1127
+ console.error(`ExecuteCursor conversation introspection: execution=${executionId}, ` +
1128
+ `turns=${turns.length}, raw=${bounded}`);
1129
+ return extractConversationErrorText(turns);
1130
+ }
1131
+ catch (introspectErr) {
1132
+ console.warn(`ExecuteCursor conversation introspection failed (non-fatal): execution=${executionId}, ` +
1133
+ `error=${introspectErr instanceof Error ? introspectErr.message : String(introspectErr)}`);
1134
+ return undefined;
1135
+ }
1136
+ }
1137
+ /**
1138
+ * Walk the last conversation turn and collect human-meaningful error text
1139
+ * (error-status payloads and `text`/`message`/`reason` strings). Schema-agnostic
1140
+ * by design so it tolerates SDK conversation-shape changes. Returns undefined
1141
+ * when nothing useful is found.
1142
+ */
1143
+ function extractConversationErrorText(turns) {
1144
+ if (!turns || turns.length === 0)
1145
+ return undefined;
1146
+ const collected = [];
1147
+ const visit = (node, depth) => {
1148
+ if (node == null || depth > 6 || typeof node !== "object")
1149
+ return;
1150
+ if (Array.isArray(node)) {
1151
+ for (const item of node)
1152
+ visit(item, depth + 1);
1153
+ return;
1154
+ }
1155
+ const obj = node;
1156
+ if (obj.status === "error" && obj.error != null) {
1157
+ collected.push(typeof obj.error === "string" ? obj.error : JSON.stringify(obj.error));
1158
+ }
1159
+ for (const [key, value] of Object.entries(obj)) {
1160
+ if ((key === "text" || key === "message" || key === "reason")
1161
+ && typeof value === "string"
1162
+ && value.trim().length > 0) {
1163
+ collected.push(value.trim());
1164
+ }
1165
+ else if (typeof value === "object" && value != null) {
1166
+ visit(value, depth + 1);
1167
+ }
1168
+ }
1169
+ };
1170
+ visit(turns[turns.length - 1], 0);
1171
+ if (collected.length === 0)
1172
+ return undefined;
1173
+ const joined = [...new Set(collected)].join(" | ");
1174
+ return joined.length > 600 ? `${joined.slice(0, 600)}…` : joined;
1175
+ }
1176
+ //# sourceMappingURL=index.js.map