@cursor/july 0.1.108 → 0.1.111

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 (1170) hide show
  1. package/AGENTS.md +3 -7
  2. package/README.md +3 -21
  3. package/dist/bin/agent-serve.js +81 -66
  4. package/dist/channels/bitbucket/api.d.ts +41 -0
  5. package/dist/channels/bitbucket/api.d.ts.map +1 -1
  6. package/dist/channels/bitbucket/api.js +266 -6
  7. package/dist/channels/bitbucket/binding.d.ts +4 -0
  8. package/dist/channels/bitbucket/binding.d.ts.map +1 -1
  9. package/dist/channels/bitbucket/binding.js +20 -4
  10. package/dist/channels/bitbucket/bitbucket-channel.js +1 -1
  11. package/dist/channels/bitbucket/bitbucket-webhook.js +1 -1
  12. package/dist/channels/bitbucket/checks.d.ts.map +1 -1
  13. package/dist/channels/bitbucket/checks.js +1 -1
  14. package/dist/channels/bitbucket/cursor-account.js +1 -1
  15. package/dist/channels/bitbucket/events.js +1 -1
  16. package/dist/channels/bitbucket/index.d.ts +1 -1
  17. package/dist/channels/bitbucket/index.d.ts.map +1 -1
  18. package/dist/channels/bitbucket/index.js +1 -1
  19. package/dist/channels/change-monitors/change-monitors-channel.js +1 -1
  20. package/dist/channels/checks.d.ts.map +1 -1
  21. package/dist/channels/checks.js +2 -2
  22. package/dist/channels/deployments/deployments-channel.js +1 -1
  23. package/dist/channels/github/cursor-account.js +3 -3
  24. package/dist/channels/github/defaults.d.ts.map +1 -1
  25. package/dist/channels/github/defaults.js +5 -3
  26. package/dist/channels/github/events.js +1 -1
  27. package/dist/channels/github/forward.js +8 -8
  28. package/dist/channels/github/github-channel.d.ts.map +1 -1
  29. package/dist/channels/github/github-channel.js +17 -13
  30. package/dist/channels/github/progress.d.ts.map +1 -1
  31. package/dist/channels/github/progress.js +7 -2
  32. package/dist/channels/github/state.d.ts +6 -0
  33. package/dist/channels/github/state.d.ts.map +1 -1
  34. package/dist/channels/github/types.d.ts +6 -0
  35. package/dist/channels/github/types.d.ts.map +1 -1
  36. package/dist/channels/gitlab/api.d.ts +27 -0
  37. package/dist/channels/gitlab/api.d.ts.map +1 -1
  38. package/dist/channels/gitlab/api.js +88 -0
  39. package/dist/channels/gitlab/binding.d.ts +5 -0
  40. package/dist/channels/gitlab/binding.d.ts.map +1 -1
  41. package/dist/channels/gitlab/binding.js +14 -4
  42. package/dist/channels/gitlab/checks.d.ts.map +1 -1
  43. package/dist/channels/gitlab/checks.js +1 -1
  44. package/dist/channels/gitlab/cursor-account.js +1 -1
  45. package/dist/channels/gitlab/events.js +1 -1
  46. package/dist/channels/gitlab/gitlab-channel.js +1 -1
  47. package/dist/channels/gitlab/gitlab-webhook.js +1 -1
  48. package/dist/channels/gitlab/index.d.ts +1 -1
  49. package/dist/channels/gitlab/index.d.ts.map +1 -1
  50. package/dist/channels/gitlab/index.js +1 -1
  51. package/dist/channels/gitlab/replay.js +2 -2
  52. package/dist/channels/origin/binding.d.ts +2 -0
  53. package/dist/channels/origin/binding.d.ts.map +1 -1
  54. package/dist/channels/origin/binding.js +3 -3
  55. package/dist/channels/origin/checks.d.ts +19 -7
  56. package/dist/channels/origin/checks.d.ts.map +1 -1
  57. package/dist/channels/origin/checks.js +13 -9
  58. package/dist/channels/origin/cursor-account.js +1 -1
  59. package/dist/channels/origin/defaults.d.ts.map +1 -1
  60. package/dist/channels/origin/defaults.js +3 -1
  61. package/dist/channels/origin/events.js +1 -1
  62. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  63. package/dist/channels/origin/origin-channel.js +2 -1
  64. package/dist/channels/origin/origin-webhook.js +2 -2
  65. package/dist/channels/slack/agentic-delivery.d.ts +23 -0
  66. package/dist/channels/slack/agentic-delivery.d.ts.map +1 -0
  67. package/dist/channels/slack/agentic-delivery.js +558 -0
  68. package/dist/channels/slack/agentic-posted.d.ts +30 -0
  69. package/dist/channels/slack/agentic-posted.d.ts.map +1 -0
  70. package/dist/channels/slack/agentic-posted.js +102 -0
  71. package/dist/channels/slack/agentic-signals.d.ts +48 -0
  72. package/dist/channels/slack/agentic-signals.d.ts.map +1 -0
  73. package/dist/channels/slack/agentic-signals.js +204 -0
  74. package/dist/channels/slack/api.d.ts +20 -1
  75. package/dist/channels/slack/api.d.ts.map +1 -1
  76. package/dist/channels/slack/api.js +43 -11
  77. package/dist/channels/slack/approvals.js +1 -1
  78. package/dist/channels/slack/auth.d.ts.map +1 -1
  79. package/dist/channels/slack/auth.js +3 -1
  80. package/dist/channels/slack/blocks.js +3 -3
  81. package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
  82. package/dist/channels/slack/bot-mentions.js +5 -5
  83. package/dist/channels/slack/channel-watch.js +1 -1
  84. package/dist/channels/slack/cli-project.js +3 -3
  85. package/dist/channels/slack/defaults.d.ts +3 -0
  86. package/dist/channels/slack/defaults.d.ts.map +1 -1
  87. package/dist/channels/slack/defaults.js +90 -29
  88. package/dist/channels/slack/dispatch.d.ts +44 -1
  89. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  90. package/dist/channels/slack/dispatch.js +233 -103
  91. package/dist/channels/slack/doctor.js +1 -1
  92. package/dist/channels/slack/eval-directive.js +1 -1
  93. package/dist/channels/slack/external-policy.d.ts +2 -1
  94. package/dist/channels/slack/external-policy.d.ts.map +1 -1
  95. package/dist/channels/slack/external-policy.js +13 -2
  96. package/dist/channels/slack/footer.d.ts +30 -0
  97. package/dist/channels/slack/footer.d.ts.map +1 -0
  98. package/dist/channels/slack/footer.js +88 -0
  99. package/dist/channels/slack/index.d.ts +2 -0
  100. package/dist/channels/slack/index.d.ts.map +1 -1
  101. package/dist/channels/slack/index.js +2 -0
  102. package/dist/channels/slack/interactive.d.ts.map +1 -1
  103. package/dist/channels/slack/interactive.js +5 -3
  104. package/dist/channels/slack/live-delivery.d.ts +1 -1
  105. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  106. package/dist/channels/slack/live-delivery.js +20 -6
  107. package/dist/channels/slack/log.d.ts.map +1 -1
  108. package/dist/channels/slack/log.js +1 -1
  109. package/dist/channels/slack/manifest.js +1 -1
  110. package/dist/channels/slack/nudge-carrier.js +1 -1
  111. package/dist/channels/slack/nudge-store.js +2 -2
  112. package/dist/channels/slack/paint-start.d.ts +22 -0
  113. package/dist/channels/slack/paint-start.d.ts.map +1 -0
  114. package/dist/channels/slack/paint-start.js +91 -0
  115. package/dist/channels/slack/placeholder.d.ts +36 -0
  116. package/dist/channels/slack/placeholder.d.ts.map +1 -0
  117. package/dist/channels/slack/placeholder.js +240 -0
  118. package/dist/channels/slack/progress-delivery.d.ts.map +1 -1
  119. package/dist/channels/slack/progress-delivery.js +13 -4
  120. package/dist/channels/slack/reasoning-chip.d.ts +8 -0
  121. package/dist/channels/slack/reasoning-chip.d.ts.map +1 -0
  122. package/dist/channels/slack/reasoning-chip.js +30 -0
  123. package/dist/channels/slack/recording-sink.d.ts +29 -0
  124. package/dist/channels/slack/recording-sink.d.ts.map +1 -0
  125. package/dist/channels/slack/recording-sink.js +142 -0
  126. package/dist/channels/slack/reply-options.d.ts +8 -1
  127. package/dist/channels/slack/reply-options.d.ts.map +1 -1
  128. package/dist/channels/slack/reply-options.js +59 -14
  129. package/dist/channels/slack/setup.js +1 -1
  130. package/dist/channels/slack/slack-channel.d.ts +12 -5
  131. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  132. package/dist/channels/slack/slack-channel.js +110 -24
  133. package/dist/channels/slack/socket-mode.js +2 -2
  134. package/dist/channels/slack/thread-context.js +5 -5
  135. package/dist/channels/slack/tool-approval-events.d.ts +5 -0
  136. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
  137. package/dist/channels/slack/tool-approval-events.js +50 -38
  138. package/dist/channels/slack/tool-cards.js +1 -1
  139. package/dist/channels/slack/tool-chip.d.ts +9 -0
  140. package/dist/channels/slack/tool-chip.d.ts.map +1 -0
  141. package/dist/channels/slack/tool-chip.js +25 -0
  142. package/dist/channels/slack/types.d.ts +49 -7
  143. package/dist/channels/slack/types.d.ts.map +1 -1
  144. package/dist/channels/slack/upload.d.ts +13 -0
  145. package/dist/channels/slack/upload.d.ts.map +1 -0
  146. package/dist/channels/slack/upload.js +135 -0
  147. package/dist/channels.d.ts +10 -14
  148. package/dist/channels.d.ts.map +1 -1
  149. package/dist/channels.js +9 -21
  150. package/dist/dashboard-session-url.d.ts +15 -0
  151. package/dist/dashboard-session-url.d.ts.map +1 -0
  152. package/dist/dashboard-session-url.js +25 -0
  153. package/dist/docs/404.html +3 -3
  154. package/dist/docs/architecture.svg +59 -0
  155. package/dist/docs/assets/app.Drol6mi6.js +309 -0
  156. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.CEGVXkmO.js} +2 -2
  157. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.CEGVXkmO.lean.js} +1 -1
  158. package/dist/docs/assets/chunks/@localSearchIndexroot.DtXk1hy-.js +1 -0
  159. package/dist/docs/assets/chunks/{VPLocalSearchBox.BOKxlYGP.js → VPLocalSearchBox.CdqoBZJX.js} +2 -2
  160. package/dist/docs/assets/chunks/arc.BVX3ycTn.js +1 -0
  161. package/dist/docs/assets/chunks/architectureDiagram-Q4EWVU46.CcChnMxX.js +36 -0
  162. package/dist/docs/assets/chunks/baseUniq.xwtXO-yt.js +1 -0
  163. package/dist/docs/assets/chunks/blockDiagram-DXYQGD6D.CijZ_taK.js +132 -0
  164. package/dist/docs/assets/chunks/c4Diagram-AHTNJAMY.0FBvwBvK.js +10 -0
  165. package/dist/docs/assets/chunks/channel.Bkv1N-gK.js +1 -0
  166. package/dist/docs/assets/chunks/chunk-4BX2VUAB.CELMmMDA.js +1 -0
  167. package/dist/docs/assets/chunks/chunk-4TB4RGXK.C4bhFtSm.js +206 -0
  168. package/dist/docs/assets/chunks/chunk-55IACEB6.ZnQ9gRRQ.js +1 -0
  169. package/dist/docs/assets/chunks/chunk-EDXVE4YY.DPlmglG-.js +1 -0
  170. package/dist/docs/assets/chunks/chunk-FMBD7UC4.BrUk8pff.js +15 -0
  171. package/dist/docs/assets/chunks/chunk-OYMX7WX6.CcmWIncu.js +231 -0
  172. package/dist/docs/assets/chunks/chunk-QZHKN3VN.D65-cs8I.js +1 -0
  173. package/dist/docs/assets/chunks/chunk-YZCP3GAM.qoXZpG9F.js +1 -0
  174. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CZDco1o8.js +1 -0
  175. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CZDco1o8.js +1 -0
  176. package/dist/docs/assets/chunks/clone.YSt_40_s.js +1 -0
  177. package/dist/docs/assets/chunks/cose-bilkent-S5V4N54A.8rYtqudO.js +1 -0
  178. package/dist/docs/assets/chunks/cytoscape.esm.BQk4lpUV.js +331 -0
  179. package/dist/docs/assets/chunks/dagre-KV5264BT.DrRP1fOh.js +4 -0
  180. package/dist/docs/assets/chunks/defaultLocale.C4B-KCzX.js +1 -0
  181. package/dist/docs/assets/chunks/diagram-5BDNPKRD.DHj_xA2_.js +10 -0
  182. package/dist/docs/assets/chunks/diagram-G4DWMVQ6.Bz_6nAKj.js +24 -0
  183. package/dist/docs/assets/chunks/diagram-MMDJMWI5.BWA0xSW9.js +43 -0
  184. package/dist/docs/assets/chunks/diagram-TYMM5635.CpTJLNJI.js +24 -0
  185. package/dist/docs/assets/chunks/erDiagram-SMLLAGMA.-7AWWSrP.js +85 -0
  186. package/dist/docs/assets/chunks/flowDiagram-DWJPFMVM.BTnQ742_.js +162 -0
  187. package/dist/docs/assets/chunks/framework.dypDpWZ3.js +19 -0
  188. package/dist/docs/assets/chunks/ganttDiagram-T4ZO3ILL.B5_HiiQ5.js +292 -0
  189. package/dist/docs/assets/chunks/gitGraphDiagram-UUTBAWPF.CZcNTFZd.js +106 -0
  190. package/dist/docs/assets/chunks/graph.V2GLaab4.js +1 -0
  191. package/dist/docs/assets/chunks/infoDiagram-42DDH7IO.7pZOkCCU.js +2 -0
  192. package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
  193. package/dist/docs/assets/chunks/ishikawaDiagram-UXIWVN3A.DSMo3Qa3.js +70 -0
  194. package/dist/docs/assets/chunks/journeyDiagram-VCZTEJTY.BNEgWN1S.js +139 -0
  195. package/dist/docs/assets/chunks/kanban-definition-6JOO6SKY.B-4d4tC7.js +89 -0
  196. package/dist/docs/assets/chunks/katex.DkKDou_j.js +257 -0
  197. package/dist/docs/assets/chunks/layout.Dvbn9nSb.js +1 -0
  198. package/dist/docs/assets/chunks/linear.D2GM4p4b.js +1 -0
  199. package/dist/docs/assets/chunks/min.DVBtLK-B.js +1 -0
  200. package/dist/docs/assets/chunks/mindmap-definition-QFDTVHPH.CnJRI55x.js +96 -0
  201. package/dist/docs/assets/chunks/ordinal.DBvzRdQf.js +1 -0
  202. package/dist/docs/assets/chunks/pieDiagram-DEJITSTG.CtoaTFlA.js +30 -0
  203. package/dist/docs/assets/chunks/quadrantDiagram-34T5L4WZ.DtT24_vN.js +7 -0
  204. package/dist/docs/assets/chunks/requirementDiagram-MS252O5E.CjSO4o8f.js +84 -0
  205. package/dist/docs/assets/chunks/sankeyDiagram-XADWPNL6.-wWiIVWa.js +10 -0
  206. package/dist/docs/assets/chunks/sequenceDiagram-FGHM5R23.DSk8s4gX.js +157 -0
  207. package/dist/docs/assets/chunks/stateDiagram-FHFEXIEX.BFKAsdkN.js +1 -0
  208. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.C4CLm481.js +1 -0
  209. package/dist/docs/assets/chunks/{theme.DbDZW-zb.js → theme.C0MctGaz.js} +2 -2
  210. package/dist/docs/assets/chunks/timeline-definition-GMOUNBTQ.TUNJbAFe.js +120 -0
  211. package/dist/docs/assets/chunks/vennDiagram-DHZGUBPP.C-RGNnk4.js +34 -0
  212. package/dist/docs/assets/chunks/virtual_mermaid-config.DDnGl6nM.js +1 -0
  213. package/dist/docs/assets/chunks/wardley-RL74JXVD.g5efOWmT.js +162 -0
  214. package/dist/docs/assets/chunks/wardleyDiagram-NUSXRM2D.DH4zt73Y.js +20 -0
  215. package/dist/docs/assets/chunks/xychartDiagram-5P7HB3ND.B-3k6bF6.js +7 -0
  216. package/dist/docs/assets/{deployment.md.JenwuCCB.js → deployment.md.Dm4Qo3hp.js} +5 -5
  217. package/dist/docs/assets/{deployment.md.JenwuCCB.lean.js → deployment.md.Dm4Qo3hp.lean.js} +1 -1
  218. package/dist/docs/assets/evals.md.BLDRt5LH.js +211 -0
  219. package/dist/docs/assets/evals.md.BLDRt5LH.lean.js +1 -0
  220. package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.js +14 -0
  221. package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.lean.js +1 -0
  222. package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.js +10 -0
  223. package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.lean.js +1 -0
  224. package/dist/docs/assets/{guides_cloud-agents.md.BsloyHdY.js → guides_cloud-agents.md.lSE_l7lH.js} +2 -2
  225. package/dist/docs/assets/{guides_cloud-agents.md.BsloyHdY.lean.js → guides_cloud-agents.md.lSE_l7lH.lean.js} +1 -1
  226. package/dist/docs/assets/{guides_convert-automation.md.B4sjlodG.js → guides_convert-automation.md.Ck6Cr68A.js} +1 -1
  227. package/dist/docs/assets/{guides_convert-automation.md.B4sjlodG.lean.js → guides_convert-automation.md.Ck6Cr68A.lean.js} +1 -1
  228. package/dist/docs/assets/{guides_github.md.BH33UEBJ.js → guides_github.md.D6ER29dG.js} +13 -3
  229. package/dist/docs/assets/{guides_github.md.BH33UEBJ.lean.js → guides_github.md.D6ER29dG.lean.js} +1 -1
  230. package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.js +14 -0
  231. package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.lean.js +1 -0
  232. package/dist/docs/assets/guides_grokbot-agents.md.WBZIOvkz.js +9 -0
  233. package/dist/docs/assets/{guides_grokbot-agents.md.DyV-WArv.lean.js → guides_grokbot-agents.md.WBZIOvkz.lean.js} +1 -1
  234. package/dist/docs/assets/{guides_improve.md.BGVk32bK.js → guides_improve.md.BKaDuKKK.js} +1 -1
  235. package/dist/docs/assets/{guides_improve.md.BGVk32bK.lean.js → guides_improve.md.BKaDuKKK.lean.js} +1 -1
  236. package/dist/docs/assets/{guides_mcp-oauth.md.Dp6cDP7f.js → guides_mcp-oauth.md.DMNMpXtO.js} +1 -1
  237. package/dist/docs/assets/{guides_mcp-oauth.md.Dp6cDP7f.lean.js → guides_mcp-oauth.md.DMNMpXtO.lean.js} +1 -1
  238. package/dist/docs/assets/{guides_opentelemetry.md.SCRMskno.js → guides_opentelemetry.md._CRfDyzH.js} +14 -14
  239. package/dist/docs/assets/{guides_opentelemetry.md.SCRMskno.lean.js → guides_opentelemetry.md._CRfDyzH.lean.js} +1 -1
  240. package/dist/docs/assets/{guides_slack.md.D4RVMM4G.js → guides_slack.md.DdT8rmsj.js} +12 -4
  241. package/dist/docs/assets/{guides_slack.md.D4RVMM4G.lean.js → guides_slack.md.DdT8rmsj.lean.js} +1 -1
  242. package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.aQW10HRe.js} +3 -3
  243. package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.aQW10HRe.lean.js} +1 -1
  244. package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.js +1 -0
  245. package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.lean.js +1 -0
  246. package/dist/docs/assets/index.md.BFVyY2KT.js +17 -0
  247. package/dist/docs/assets/index.md.BFVyY2KT.lean.js +1 -0
  248. package/dist/docs/assets/{quickstart.md.DdQOF7Y8.js → quickstart.md.D3MjSZN-.js} +30 -38
  249. package/dist/docs/assets/quickstart.md.D3MjSZN-.lean.js +1 -0
  250. package/dist/docs/assets/{reference_agent-config.md.CvoL6pof.js → reference_agent-config.md.CfVA-LZJ.js} +1 -1
  251. package/dist/docs/assets/{reference_agent-config.md.CvoL6pof.lean.js → reference_agent-config.md.CfVA-LZJ.lean.js} +1 -1
  252. package/dist/docs/assets/{reference_artifacts.md.Dior32Qw.js → reference_artifacts.md.Vf7qyIZ-.js} +1 -1
  253. package/dist/docs/assets/{reference_artifacts.md.Dior32Qw.lean.js → reference_artifacts.md.Vf7qyIZ-.lean.js} +1 -1
  254. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.icqLKcTc.js} +2 -12
  255. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.icqLKcTc.lean.js} +1 -1
  256. package/dist/docs/assets/{reference_cli.md.Ca26u0Es.js → reference_cli.md.B2dBL6L8.js} +4 -4
  257. package/dist/docs/assets/{reference_cli.md.Ca26u0Es.lean.js → reference_cli.md.B2dBL6L8.lean.js} +1 -1
  258. package/dist/docs/assets/{reference_connections.md.BojkC6c5.js → reference_connections.md.Cb3U_c8n.js} +4 -4
  259. package/dist/docs/assets/{reference_connections.md.BojkC6c5.lean.js → reference_connections.md.Cb3U_c8n.lean.js} +1 -1
  260. package/dist/docs/assets/{reference_extensions.md.CPWt00ds.js → reference_extensions.md.wlFD3cUR.js} +3 -3
  261. package/dist/docs/assets/{reference_extensions.md.CPWt00ds.lean.js → reference_extensions.md.wlFD3cUR.lean.js} +1 -1
  262. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.CZuynAxj.js} +3 -3
  263. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.CZuynAxj.lean.js} +1 -1
  264. package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.DTKcYE6L.js} +3 -3
  265. package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.DTKcYE6L.lean.js} +1 -1
  266. package/dist/docs/assets/{reference_instructions.md.CR7XSsGk.js → reference_instructions.md.D7gkckK-.js} +1 -1
  267. package/dist/docs/assets/{reference_instructions.md.CR7XSsGk.lean.js → reference_instructions.md.D7gkckK-.lean.js} +1 -1
  268. package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.D2YExv5K.js} +1 -1
  269. package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.D2YExv5K.lean.js} +1 -1
  270. package/dist/docs/assets/reference_project-layout.md.DPxbUJyt.js +19 -0
  271. package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.DPxbUJyt.lean.js} +1 -1
  272. package/dist/docs/assets/{reference_prompt.md.DnaD5dNK.js → reference_prompt.md.BQ5uAv1F.js} +1 -1
  273. package/dist/docs/assets/{reference_prompt.md.DnaD5dNK.lean.js → reference_prompt.md.BQ5uAv1F.lean.js} +1 -1
  274. package/dist/docs/assets/{reference_schedules.md.DI_JrHgq.js → reference_schedules.md.BasfZWO-.js} +1 -1
  275. package/dist/docs/assets/{reference_schedules.md.DI_JrHgq.lean.js → reference_schedules.md.BasfZWO-.lean.js} +1 -1
  276. package/dist/docs/assets/reference_sessions.md.YKvIsWAx.js +1 -0
  277. package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.YKvIsWAx.lean.js} +1 -1
  278. package/dist/docs/assets/{reference_skills.md.l2ezAcaN.js → reference_skills.md.rNgpsGd0.js} +1 -1
  279. package/dist/docs/assets/{reference_skills.md.l2ezAcaN.lean.js → reference_skills.md.rNgpsGd0.lean.js} +1 -1
  280. package/dist/docs/assets/{reference_subagents.md.CfsIloPm.js → reference_subagents.md.e5qitjJt.js} +2 -2
  281. package/dist/docs/assets/{reference_subagents.md.CfsIloPm.lean.js → reference_subagents.md.e5qitjJt.lean.js} +1 -1
  282. package/dist/docs/assets/{reference_tools.md.aGrn99hP.js → reference_tools.md.BdCO2aHZ.js} +4 -4
  283. package/dist/docs/assets/{reference_tools.md.aGrn99hP.lean.js → reference_tools.md.BdCO2aHZ.lean.js} +1 -1
  284. package/dist/docs/assets/{style.DCD_zyg3.css → style.Cfo2vbik.css} +1 -1
  285. package/dist/docs/assets/{templates_agentic-owners.md.BZSH4N9z.js → templates_agentic-owners.md.Da_AGDlH.js} +1 -1
  286. package/dist/docs/assets/{templates_agentic-owners.md.BZSH4N9z.lean.js → templates_agentic-owners.md.Da_AGDlH.lean.js} +1 -1
  287. package/dist/docs/assets/{templates_pr-autofixer.md.Bds_XWcV.js → templates_pr-autofixer.md.DqxocIGh.js} +1 -1
  288. package/dist/docs/assets/{templates_pr-autofixer.md.Bds_XWcV.lean.js → templates_pr-autofixer.md.DqxocIGh.lean.js} +1 -1
  289. package/dist/docs/assets/{templates_security-reviewer.md.lshxbCLK.js → templates_security-reviewer.md.Bhnvd8VE.js} +1 -1
  290. package/dist/docs/assets/{templates_security-reviewer.md.lshxbCLK.lean.js → templates_security-reviewer.md.Bhnvd8VE.lean.js} +1 -1
  291. package/dist/docs/assets/{templates_triage.md.Co4UNzkZ.js → templates_triage.md.BdBWO9Ic.js} +1 -1
  292. package/dist/docs/assets/{templates_triage.md.Co4UNzkZ.lean.js → templates_triage.md.BdBWO9Ic.lean.js} +1 -1
  293. package/dist/docs/assets/{troubleshooting.md.CYEAO9bM.js → troubleshooting.md.BcgNoYtJ.js} +1 -1
  294. package/dist/docs/assets/{troubleshooting.md.CYEAO9bM.lean.js → troubleshooting.md.BcgNoYtJ.lean.js} +1 -1
  295. package/dist/docs/building-with-agents.html +41 -8
  296. package/dist/docs/building-with-agents.md +15 -16
  297. package/dist/docs/deployment.html +44 -11
  298. package/dist/docs/deployment.md +6 -7
  299. package/dist/docs/evals.html +196 -37
  300. package/dist/docs/evals.md +612 -297
  301. package/dist/docs/guides/agent-to-agent.html +48 -11
  302. package/dist/docs/guides/agent-to-agent.md +40 -83
  303. package/dist/docs/guides/bitbucket.html +69 -0
  304. package/dist/docs/guides/bitbucket.md +84 -0
  305. package/dist/docs/guides/cloud-agents.html +41 -8
  306. package/dist/docs/guides/cloud-agents.md +24 -20
  307. package/dist/docs/guides/convert-automation.html +41 -8
  308. package/dist/docs/guides/github.html +52 -9
  309. package/dist/docs/guides/github.md +32 -1
  310. package/dist/docs/guides/gitlab.html +73 -0
  311. package/dist/docs/guides/gitlab.md +92 -0
  312. package/dist/docs/guides/grokbot-agents.html +41 -8
  313. package/dist/docs/guides/grokbot-agents.md +26 -19
  314. package/dist/docs/guides/improve.html +41 -8
  315. package/dist/docs/guides/mcp-oauth.html +41 -8
  316. package/dist/docs/guides/mcp-oauth.md +1 -1
  317. package/dist/docs/guides/opentelemetry.html +53 -20
  318. package/dist/docs/guides/opentelemetry.md +28 -41
  319. package/dist/docs/guides/slack.html +51 -10
  320. package/dist/docs/guides/slack.md +53 -4
  321. package/dist/docs/guides/webhooks.html +42 -9
  322. package/dist/docs/guides/webhooks.md +7 -6
  323. package/dist/docs/hashmap.json +1 -1
  324. package/dist/docs/hillclimbing.html +40 -10
  325. package/dist/docs/hillclimbing.md +7 -7
  326. package/dist/docs/index.html +57 -12
  327. package/dist/docs/index.md +81 -146
  328. package/dist/docs/llms-full.txt +1368 -5551
  329. package/dist/docs/llms.txt +6 -31
  330. package/dist/docs/quickstart.html +70 -45
  331. package/dist/docs/quickstart.md +44 -105
  332. package/dist/docs/reference/agent-config.html +41 -8
  333. package/dist/docs/reference/artifacts.html +41 -8
  334. package/dist/docs/reference/channels.html +41 -18
  335. package/dist/docs/reference/channels.md +16 -19
  336. package/dist/docs/reference/cli.html +43 -10
  337. package/dist/docs/reference/cli.md +6 -20
  338. package/dist/docs/reference/connections.html +43 -10
  339. package/dist/docs/reference/connections.md +3 -5
  340. package/dist/docs/reference/extensions.html +43 -10
  341. package/dist/docs/reference/extensions.md +2 -5
  342. package/dist/docs/reference/hooks.html +42 -9
  343. package/dist/docs/reference/hooks.md +11 -16
  344. package/dist/docs/reference/http-api.html +42 -9
  345. package/dist/docs/reference/http-api.md +6 -7
  346. package/dist/docs/reference/instructions.html +41 -8
  347. package/dist/docs/reference/playground.html +40 -7
  348. package/dist/docs/reference/playground.md +2 -6
  349. package/dist/docs/reference/project-layout.html +42 -9
  350. package/dist/docs/reference/project-layout.md +4 -12
  351. package/dist/docs/reference/prompt.html +41 -8
  352. package/dist/docs/reference/schedules.html +41 -8
  353. package/dist/docs/reference/sessions.html +40 -7
  354. package/dist/docs/reference/sessions.md +6 -6
  355. package/dist/docs/reference/skills.html +41 -8
  356. package/dist/docs/reference/subagents.html +41 -8
  357. package/dist/docs/reference/subagents.md +2 -4
  358. package/dist/docs/reference/tools.html +43 -10
  359. package/dist/docs/reference/tools.md +2 -5
  360. package/dist/docs/templates/agentic-owners.html +41 -8
  361. package/dist/docs/templates/pr-autofixer.html +41 -8
  362. package/dist/docs/templates/security-reviewer.html +41 -8
  363. package/dist/docs/templates/triage.html +41 -8
  364. package/dist/docs/troubleshooting.html +40 -7
  365. package/dist/docs/troubleshooting.md +1 -2
  366. package/dist/evals/assertions.js +19 -19
  367. package/dist/evals/expect.js +1 -1
  368. package/dist/evals/judge.js +1 -1
  369. package/dist/evals/reporters.d.ts.map +1 -1
  370. package/dist/evals/reporters.js +8 -8
  371. package/dist/evals/run-facts.js +2 -2
  372. package/dist/evals.d.ts +1 -1
  373. package/dist/evals.d.ts.map +1 -1
  374. package/dist/evals.js +7 -7
  375. package/dist/extensions/cursor-cloud-agents/extension.js +1 -1
  376. package/dist/extensions/cursor-cloud-agents/lib/backend.js +3 -3
  377. package/dist/extensions/cursor-cloud-agents/lib/fleet.js +1 -1
  378. package/dist/extensions/cursor-cloud-agents/lib/repos.js +6 -6
  379. package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts.map +1 -1
  380. package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -2
  381. package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
  382. package/dist/extensions/improve/skills/yourself.js +1 -1
  383. package/dist/extensions/slack-communication/extension.d.ts +28 -0
  384. package/dist/extensions/slack-communication/extension.d.ts.map +1 -0
  385. package/dist/extensions/slack-communication/extension.js +32 -0
  386. package/dist/extensions/slack-communication/skills/slack-voice.d.ts +5 -0
  387. package/dist/extensions/slack-communication/skills/slack-voice.d.ts.map +1 -0
  388. package/dist/extensions/slack-communication/skills/slack-voice.js +54 -0
  389. package/dist/extensions/slack-communication/tools/delete-message.d.ts +4 -0
  390. package/dist/extensions/slack-communication/tools/delete-message.d.ts.map +1 -0
  391. package/dist/extensions/slack-communication/tools/delete-message.js +29 -0
  392. package/dist/extensions/slack-communication/tools/edit-message.d.ts +4 -0
  393. package/dist/extensions/slack-communication/tools/edit-message.d.ts.map +1 -0
  394. package/dist/extensions/slack-communication/tools/edit-message.js +37 -0
  395. package/dist/extensions/slack-communication/tools/post-card.d.ts +4 -0
  396. package/dist/extensions/slack-communication/tools/post-card.d.ts.map +1 -0
  397. package/dist/extensions/slack-communication/tools/post-card.js +25 -0
  398. package/dist/extensions/slack-communication/tools/post-file.d.ts +4 -0
  399. package/dist/extensions/slack-communication/tools/post-file.d.ts.map +1 -0
  400. package/dist/extensions/slack-communication/tools/post-file.js +76 -0
  401. package/dist/extensions/slack-communication/tools/post-update.d.ts +4 -0
  402. package/dist/extensions/slack-communication/tools/post-update.d.ts.map +1 -0
  403. package/dist/extensions/slack-communication/tools/post-update.js +36 -0
  404. package/dist/extensions/slack-communication/tools/react.d.ts +4 -0
  405. package/dist/extensions/slack-communication/tools/react.d.ts.map +1 -0
  406. package/dist/extensions/slack-communication/tools/react.js +27 -0
  407. package/dist/extensions/slack-communication/tools/set-status.d.ts +4 -0
  408. package/dist/extensions/slack-communication/tools/set-status.d.ts.map +1 -0
  409. package/dist/extensions/slack-communication/tools/set-status.js +18 -0
  410. package/dist/extensions.d.ts +2 -3
  411. package/dist/extensions.d.ts.map +1 -1
  412. package/dist/extensions.js +2 -5
  413. package/dist/files-backends/cursor-hosted.d.ts +18 -6
  414. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  415. package/dist/files-backends/cursor-hosted.js +357 -74
  416. package/dist/files-backends/local-fs.js +1 -1
  417. package/dist/files.d.ts +15 -0
  418. package/dist/files.d.ts.map +1 -1
  419. package/dist/filesystem.d.ts.map +1 -1
  420. package/dist/filesystem.js +15 -15
  421. package/dist/index.d.ts +6 -10
  422. package/dist/index.d.ts.map +1 -1
  423. package/dist/index.js +5 -8
  424. package/dist/internal/advertise-tools.js +6 -6
  425. package/dist/internal/approval-gate.js +1 -1
  426. package/dist/internal/artifacts-store.js +3 -3
  427. package/dist/internal/as-of.js +2 -2
  428. package/dist/internal/authored-alias-hooks.d.ts +5 -0
  429. package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
  430. package/dist/internal/authored-alias-hooks.js +17 -0
  431. package/dist/internal/authored-loaders.d.ts +4 -0
  432. package/dist/internal/authored-loaders.d.ts.map +1 -1
  433. package/dist/internal/authored-loaders.js +21 -2
  434. package/dist/internal/builtin-tools/reminders.js +2 -2
  435. package/dist/internal/chat-client.js +5 -5
  436. package/dist/internal/cli-ax.d.ts +2 -2
  437. package/dist/internal/cli-ax.d.ts.map +1 -1
  438. package/dist/internal/cli-ax.js +69 -15
  439. package/dist/internal/cli-bitbucket.js +10 -10
  440. package/dist/internal/cli-convert-automation.js +2 -2
  441. package/dist/internal/cli-cursor.d.ts +3 -11
  442. package/dist/internal/cli-cursor.d.ts.map +1 -1
  443. package/dist/internal/cli-cursor.js +5 -10
  444. package/dist/internal/cli-deploy.d.ts +12 -2
  445. package/dist/internal/cli-deploy.d.ts.map +1 -1
  446. package/dist/internal/cli-deploy.js +328 -96
  447. package/dist/internal/cli-docs.js +5 -5
  448. package/dist/internal/cli-github.js +15 -16
  449. package/dist/internal/cli-gitlab.js +10 -10
  450. package/dist/internal/cli-manifest.js +1 -1
  451. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  452. package/dist/internal/cli-mcp-oauth.js +5 -5
  453. package/dist/internal/cli-mcp.js +3 -3
  454. package/dist/internal/cli-skills.js +2 -2
  455. package/dist/internal/cli-slack.js +5 -5
  456. package/dist/internal/cloud-turn-cost.js +1 -1
  457. package/dist/internal/continuation-channel.d.ts.map +1 -1
  458. package/dist/internal/continuation-channel.js +2 -2
  459. package/dist/internal/continuation-identity.d.ts.map +1 -1
  460. package/dist/internal/continuation-identity.js +22 -12
  461. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  462. package/dist/internal/conversation-mirror.js +33 -2
  463. package/dist/internal/convert-automation/convert-workflow.js +25 -24
  464. package/dist/internal/convert-automation/types.d.ts +8 -0
  465. package/dist/internal/convert-automation/types.d.ts.map +1 -1
  466. package/dist/internal/cursor/account-mcp.d.ts +2 -2
  467. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  468. package/dist/internal/cursor/account-mcp.js +32 -27
  469. package/dist/internal/cursor/backend-client.d.ts +15 -10
  470. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  471. package/dist/internal/cursor/backend-client.js +17 -11
  472. package/dist/internal/cursor/credentials.js +1 -1
  473. package/dist/internal/cursor/hosted-store-secrets.d.ts +16 -0
  474. package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -1
  475. package/dist/internal/cursor/hosted-store-secrets.js +25 -0
  476. package/dist/internal/cursor-account-mcp-auth.js +9 -9
  477. package/dist/internal/cursor-deployment-relay.js +9 -9
  478. package/dist/internal/cursor-event-relay.js +10 -10
  479. package/dist/internal/cursor-relay-core.js +2 -2
  480. package/dist/internal/deploy-client.d.ts +106 -9
  481. package/dist/internal/deploy-client.d.ts.map +1 -1
  482. package/dist/internal/deploy-client.js +171 -23
  483. package/dist/internal/deploy-manifest.d.ts +13 -0
  484. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  485. package/dist/internal/deploy-manifest.js +32 -16
  486. package/dist/internal/discovery/agent-config.d.ts +5 -0
  487. package/dist/internal/discovery/agent-config.d.ts.map +1 -1
  488. package/dist/internal/discovery/agent-config.js +27 -0
  489. package/dist/internal/discovery/agent.d.ts +1 -1
  490. package/dist/internal/discovery/agent.d.ts.map +1 -1
  491. package/dist/internal/discovery/agent.js +10 -13
  492. package/dist/internal/discovery/channels.js +4 -4
  493. package/dist/internal/discovery/connections.js +4 -4
  494. package/dist/internal/discovery/cursor-plugin.js +12 -12
  495. package/dist/internal/discovery/extension-overlay.d.ts +1 -2
  496. package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
  497. package/dist/internal/discovery/extension-overlay.js +3 -17
  498. package/dist/internal/discovery/extensions.d.ts +1 -2
  499. package/dist/internal/discovery/extensions.d.ts.map +1 -1
  500. package/dist/internal/discovery/extensions.js +10 -28
  501. package/dist/internal/discovery/info.d.ts.map +1 -1
  502. package/dist/internal/discovery/info.js +44 -26
  503. package/dist/internal/discovery/instructions.js +1 -1
  504. package/dist/internal/discovery/modules.js +0 -1
  505. package/dist/internal/discovery/project.d.ts.map +1 -1
  506. package/dist/internal/discovery/project.js +4 -20
  507. package/dist/internal/discovery/services.js +1 -1
  508. package/dist/internal/discovery/tools.js +1 -1
  509. package/dist/internal/docs-site.js +2 -2
  510. package/dist/internal/env-file.js +1 -1
  511. package/dist/internal/eval-run-store.d.ts.map +1 -1
  512. package/dist/internal/eval-run-store.js +7 -7
  513. package/dist/internal/eval-runner.js +14 -15
  514. package/dist/internal/evals-client.js +4 -4
  515. package/dist/internal/event-log.js +8 -8
  516. package/dist/internal/event-mapper.d.ts +18 -0
  517. package/dist/internal/event-mapper.d.ts.map +1 -1
  518. package/dist/internal/event-mapper.js +34 -2
  519. package/dist/internal/filesystem/format.d.ts.map +1 -1
  520. package/dist/internal/filesystem/format.js +6 -3
  521. package/dist/internal/filesystem/scratch.js +3 -3
  522. package/dist/internal/filesystem/tools.d.ts.map +1 -1
  523. package/dist/internal/filesystem/tools.js +6 -6
  524. package/dist/internal/filesystem/walk.js +1 -1
  525. package/dist/internal/framework-file-storage.d.ts +10 -7
  526. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  527. package/dist/internal/framework-file-storage.js +95 -7
  528. package/dist/internal/framework-storage-selection.d.ts +2 -8
  529. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  530. package/dist/internal/framework-storage-selection.js +4 -13
  531. package/dist/internal/github-fanout.js +3 -3
  532. package/dist/internal/guest-network.js +4 -4
  533. package/dist/internal/host-files.js +1 -1
  534. package/dist/internal/host-kv.js +2 -2
  535. package/dist/internal/hosted-admission-adapter.d.ts +2 -0
  536. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  537. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
  538. package/dist/internal/hosted-catch-protocol.js +2 -4
  539. package/dist/internal/hosted-catch.js +1 -1
  540. package/dist/internal/hosted-delivery-protocol.d.ts +29 -0
  541. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  542. package/dist/internal/hosted-delivery-protocol.js +76 -8
  543. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  544. package/dist/internal/hosted-delivery.js +201 -64
  545. package/dist/internal/hosted-execution-diag.js +3 -3
  546. package/dist/internal/hosted-execution-latency.d.ts +80 -0
  547. package/dist/internal/hosted-execution-latency.d.ts.map +1 -0
  548. package/dist/internal/hosted-execution-latency.js +220 -0
  549. package/dist/internal/hosting.d.ts +5 -5
  550. package/dist/internal/hosting.d.ts.map +1 -1
  551. package/dist/internal/hosting.js +5 -6
  552. package/dist/internal/http-channel-define.d.ts +11 -0
  553. package/dist/internal/http-channel-define.d.ts.map +1 -0
  554. package/dist/internal/http-channel-define.js +18 -0
  555. package/dist/internal/http-channel.d.ts +2 -3
  556. package/dist/internal/http-channel.d.ts.map +1 -1
  557. package/dist/internal/http-channel.js +3 -4
  558. package/dist/internal/http-control-plane-session.d.ts +7 -3
  559. package/dist/internal/http-control-plane-session.d.ts.map +1 -1
  560. package/dist/internal/http-control-plane-session.js +22 -10
  561. package/dist/internal/incoming-headers-to-fetch.d.ts +10 -0
  562. package/dist/internal/incoming-headers-to-fetch.d.ts.map +1 -0
  563. package/dist/internal/incoming-headers-to-fetch.js +41 -0
  564. package/dist/internal/init-interview.js +7 -7
  565. package/dist/internal/init-project.d.ts.map +1 -1
  566. package/dist/internal/init-project.js +14 -14
  567. package/dist/internal/init-scaffold.d.ts.map +1 -1
  568. package/dist/internal/init-scaffold.js +2 -3
  569. package/dist/internal/inline-stdio-mcp.js +2 -2
  570. package/dist/internal/install-cursor-skills.d.ts +5 -2
  571. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  572. package/dist/internal/install-cursor-skills.js +35 -15
  573. package/dist/internal/json-schema.js +1 -1
  574. package/dist/internal/local-control-plane.d.ts.map +1 -1
  575. package/dist/internal/local-control-plane.js +3 -3
  576. package/dist/internal/local-env.js +3 -3
  577. package/dist/internal/log-ring.js +1 -1
  578. package/dist/internal/logs-client.js +1 -1
  579. package/dist/internal/mcp-endpoint.js +8 -8
  580. package/dist/internal/mcp-host.js +4 -4
  581. package/dist/internal/mcp-oauth-on-demand.js +3 -3
  582. package/dist/internal/mcp-oauth.js +5 -5
  583. package/dist/internal/net.js +2 -2
  584. package/dist/internal/otel/config.js +3 -3
  585. package/dist/internal/otel/runtime.js +13 -13
  586. package/dist/internal/peer-connections.js +2 -2
  587. package/dist/internal/platform-schedule-sync.js +1 -1
  588. package/dist/internal/platform-timers.js +1 -1
  589. package/dist/internal/playground/static.js +2 -2
  590. package/dist/internal/playground/toolchain.js +2 -2
  591. package/dist/internal/playground-proxy.js +3 -3
  592. package/dist/internal/process-memory-telemetry.js +1 -1
  593. package/dist/internal/reminder-runner.d.ts.map +1 -1
  594. package/dist/internal/reminder-runner.js +7 -7
  595. package/dist/internal/reminder-store.js +1 -1
  596. package/dist/internal/request-error-status.d.ts.map +1 -1
  597. package/dist/internal/request-error-status.js +9 -0
  598. package/dist/internal/resolved-connections.js +8 -8
  599. package/dist/internal/result-output.d.ts +14 -2
  600. package/dist/internal/result-output.d.ts.map +1 -1
  601. package/dist/internal/result-output.js +45 -2
  602. package/dist/internal/router.js +4 -4
  603. package/dist/internal/run-client.d.ts +1 -1
  604. package/dist/internal/run-client.js +2 -2
  605. package/dist/internal/schedule-runner.js +6 -6
  606. package/dist/internal/scm/pr-url.d.ts +3 -1
  607. package/dist/internal/scm/pr-url.d.ts.map +1 -1
  608. package/dist/internal/scm/pr-url.js +10 -2
  609. package/dist/internal/sdk-runner.d.ts.map +1 -1
  610. package/dist/internal/sdk-runner.js +15 -16
  611. package/dist/internal/serve-restart.js +1 -1
  612. package/dist/internal/server.d.ts.map +1 -1
  613. package/dist/internal/server.js +81 -101
  614. package/dist/internal/session-cost.js +3 -3
  615. package/dist/internal/session-engine.d.ts +39 -35
  616. package/dist/internal/session-engine.d.ts.map +1 -1
  617. package/dist/internal/session-engine.js +394 -343
  618. package/dist/internal/session-run-log.d.ts.map +1 -1
  619. package/dist/internal/session-run-log.js +4 -4
  620. package/dist/internal/session-store.d.ts +47 -3
  621. package/dist/internal/session-store.d.ts.map +1 -1
  622. package/dist/internal/session-store.js +198 -33
  623. package/dist/internal/sessions-client.js +3 -3
  624. package/dist/internal/slack-thread-key.d.ts +7 -0
  625. package/dist/internal/slack-thread-key.d.ts.map +1 -0
  626. package/dist/internal/slack-thread-key.js +10 -0
  627. package/dist/internal/sleep.js +1 -1
  628. package/dist/internal/storage-coordinator.d.ts +22 -19
  629. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  630. package/dist/internal/storage-coordinator.js +114 -73
  631. package/dist/internal/storage-roles.d.ts +4 -9
  632. package/dist/internal/storage-roles.d.ts.map +1 -1
  633. package/dist/internal/storage-roles.js +2 -2
  634. package/dist/internal/storage.d.ts +2 -0
  635. package/dist/internal/storage.d.ts.map +1 -0
  636. package/dist/internal/storage.js +1 -0
  637. package/dist/internal/store-mirror.js +4 -4
  638. package/dist/internal/terminal-style.js +2 -2
  639. package/dist/internal/tool-result.js +3 -3
  640. package/dist/internal/trajectory.js +7 -7
  641. package/dist/internal/turn-governor.js +2 -2
  642. package/dist/internal/turn-outbox.js +1 -1
  643. package/dist/internal/update-check.js +2 -2
  644. package/dist/internal/v2-hosting.d.ts +9 -0
  645. package/dist/internal/v2-hosting.d.ts.map +1 -1
  646. package/dist/internal/v2-hosting.js +10 -0
  647. package/dist/internal/workspace.d.ts +13 -10
  648. package/dist/internal/workspace.d.ts.map +1 -1
  649. package/dist/internal/workspace.js +17 -16
  650. package/dist/kv/memory-kv.d.ts +6 -4
  651. package/dist/kv/memory-kv.d.ts.map +1 -1
  652. package/dist/kv/memory-kv.js +9 -7
  653. package/dist/kv.d.ts +4 -7
  654. package/dist/kv.d.ts.map +1 -1
  655. package/dist/kv.js +4 -7
  656. package/dist/otel-public.d.ts +7 -0
  657. package/dist/otel-public.d.ts.map +1 -0
  658. package/dist/otel-public.js +5 -0
  659. package/dist/otel.d.ts +7 -2
  660. package/dist/otel.d.ts.map +1 -1
  661. package/dist/otel.js +7 -2
  662. package/dist/playground/assets/index-BLlKgZtI.css +1 -0
  663. package/dist/playground/assets/index-CDS5p9sR.js +67 -0
  664. package/dist/playground/index.html +2 -2
  665. package/dist/prompt.js +1 -1
  666. package/dist/result.d.ts +10 -4
  667. package/dist/result.d.ts.map +1 -1
  668. package/dist/result.js +9 -3
  669. package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
  670. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
  671. package/dist/storage-backends/cursor-hosted-v2.js +6 -7
  672. package/dist/storage-backends/cursor-hosted.d.ts +6 -19
  673. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  674. package/dist/storage-backends/cursor-hosted.js +6 -50
  675. package/dist/storage-backends/file-kv.d.ts +9 -12
  676. package/dist/storage-backends/file-kv.d.ts.map +1 -1
  677. package/dist/storage-backends/file-kv.js +18 -54
  678. package/dist/storage-protocol.d.ts +3 -11
  679. package/dist/storage-protocol.d.ts.map +1 -1
  680. package/dist/storage-protocol.js +3 -11
  681. package/dist/storage.d.ts +28 -38
  682. package/dist/storage.d.ts.map +1 -1
  683. package/dist/storage.js +15 -50
  684. package/dist/types.d.ts +87 -68
  685. package/dist/types.d.ts.map +1 -1
  686. package/dist/types.js +12 -4
  687. package/docs/README.md +83 -148
  688. package/docs/building-with-agents.md +15 -16
  689. package/docs/deployment.md +6 -7
  690. package/docs/evals.md +613 -298
  691. package/docs/guides/agent-to-agent.md +41 -84
  692. package/docs/guides/bitbucket.md +89 -0
  693. package/docs/guides/cloud-agents.md +25 -20
  694. package/docs/guides/github.md +32 -1
  695. package/docs/guides/gitlab.md +97 -0
  696. package/docs/guides/grokbot-agents.md +27 -19
  697. package/docs/guides/mcp-oauth.md +1 -1
  698. package/docs/guides/opentelemetry.md +28 -41
  699. package/docs/guides/slack.md +53 -4
  700. package/docs/guides/webhooks.md +7 -6
  701. package/docs/hillclimbing.md +7 -7
  702. package/docs/quickstart.md +45 -106
  703. package/docs/reference/channels.md +16 -19
  704. package/docs/reference/cli.md +6 -20
  705. package/docs/reference/connections.md +3 -5
  706. package/docs/reference/extensions.md +2 -5
  707. package/docs/reference/hooks.md +11 -16
  708. package/docs/reference/http-api.md +6 -7
  709. package/docs/reference/playground.md +2 -6
  710. package/docs/reference/project-layout.md +4 -12
  711. package/docs/reference/sessions.md +6 -6
  712. package/docs/reference/subagents.md +2 -4
  713. package/docs/reference/tools.md +2 -5
  714. package/docs/troubleshooting.md +1 -2
  715. package/package.json +55 -43
  716. package/skills/deploy/SKILL.md +169 -0
  717. package/skills/evals/SKILL.md +45 -8
  718. package/skills/framework-map/SKILL.md +3 -4
  719. package/skills/otel/SKILL.md +8 -18
  720. package/src/bin/agent-serve.ts +93 -72
  721. package/src/channels/bitbucket/api.ts +347 -6
  722. package/src/channels/bitbucket/binding.ts +29 -4
  723. package/src/channels/bitbucket/bitbucket-channel.ts +1 -1
  724. package/src/channels/bitbucket/bitbucket-webhook.ts +1 -1
  725. package/src/channels/bitbucket/checks.ts +3 -4
  726. package/src/channels/bitbucket/cursor-account.ts +1 -1
  727. package/src/channels/bitbucket/events.ts +1 -1
  728. package/src/channels/bitbucket/index.ts +2 -0
  729. package/src/channels/change-monitors/change-monitors-channel.ts +2 -2
  730. package/src/channels/checks.ts +5 -4
  731. package/src/channels/deployments/deployments-channel.ts +1 -1
  732. package/src/channels/github/api.ts +1 -1
  733. package/src/channels/github/checks.ts +1 -1
  734. package/src/channels/github/cursor-account.ts +3 -3
  735. package/src/channels/github/defaults.ts +8 -4
  736. package/src/channels/github/events.ts +1 -1
  737. package/src/channels/github/forward.ts +8 -8
  738. package/src/channels/github/github-channel.ts +19 -2
  739. package/src/channels/github/progress.ts +7 -2
  740. package/src/channels/github/state.ts +6 -0
  741. package/src/channels/github/types.ts +6 -0
  742. package/src/channels/gitlab/api.ts +123 -0
  743. package/src/channels/gitlab/binding.ts +16 -4
  744. package/src/channels/gitlab/checks.ts +3 -4
  745. package/src/channels/gitlab/cursor-account.ts +1 -1
  746. package/src/channels/gitlab/events.ts +1 -1
  747. package/src/channels/gitlab/gitlab-channel.ts +1 -1
  748. package/src/channels/gitlab/gitlab-webhook.ts +1 -1
  749. package/src/channels/gitlab/index.ts +1 -0
  750. package/src/channels/gitlab/replay.ts +2 -2
  751. package/src/channels/origin/binding.ts +6 -3
  752. package/src/channels/origin/checks.ts +27 -17
  753. package/src/channels/origin/cursor-account.ts +1 -1
  754. package/src/channels/origin/defaults.ts +5 -1
  755. package/src/channels/origin/events.ts +1 -1
  756. package/src/channels/origin/origin-channel.ts +2 -1
  757. package/src/channels/origin/origin-webhook.ts +2 -2
  758. package/src/channels/slack/agentic-delivery.ts +659 -0
  759. package/src/channels/slack/agentic-posted.ts +148 -0
  760. package/src/channels/slack/agentic-signals.ts +248 -0
  761. package/src/channels/slack/api.ts +51 -11
  762. package/src/channels/slack/approvals.ts +1 -1
  763. package/src/channels/slack/attachments.ts +1 -1
  764. package/src/channels/slack/auth.ts +3 -1
  765. package/src/channels/slack/blocks.ts +3 -3
  766. package/src/channels/slack/bot-mentions.ts +5 -7
  767. package/src/channels/slack/channel-watch.ts +1 -1
  768. package/src/channels/slack/cli-project.ts +3 -3
  769. package/src/channels/slack/defaults.ts +109 -37
  770. package/src/channels/slack/dispatch.ts +323 -164
  771. package/src/channels/slack/doctor.ts +1 -1
  772. package/src/channels/slack/eval-directive.ts +1 -1
  773. package/src/channels/slack/external-policy.ts +15 -2
  774. package/src/channels/slack/footer.ts +108 -0
  775. package/src/channels/slack/index.ts +2 -0
  776. package/src/channels/slack/interactive.ts +4 -2
  777. package/src/channels/slack/live-delivery.ts +23 -7
  778. package/src/channels/slack/log.ts +1 -1
  779. package/src/channels/slack/manifest.ts +1 -1
  780. package/src/channels/slack/nudge-carrier.ts +1 -1
  781. package/src/channels/slack/nudge-store.ts +2 -2
  782. package/src/channels/slack/paint-start.ts +93 -0
  783. package/src/channels/slack/placeholder.ts +315 -0
  784. package/src/channels/slack/progress-delivery.ts +14 -1
  785. package/src/channels/slack/reasoning-chip.ts +48 -0
  786. package/src/channels/slack/recording-sink.ts +176 -0
  787. package/src/channels/slack/reply-options.ts +71 -15
  788. package/src/channels/slack/setup.ts +1 -1
  789. package/src/channels/slack/slack-channel.ts +140 -18
  790. package/src/channels/slack/socket-mode.ts +2 -2
  791. package/src/channels/slack/thread-context.ts +5 -5
  792. package/src/channels/slack/tool-approval-events.ts +54 -38
  793. package/src/channels/slack/tool-cards.ts +1 -1
  794. package/src/channels/slack/tool-chip.ts +36 -0
  795. package/src/channels/slack/types.ts +47 -7
  796. package/src/channels/slack/upload.ts +142 -0
  797. package/src/channels.ts +12 -30
  798. package/src/dashboard-session-url.ts +32 -0
  799. package/src/evals/assertions.ts +19 -19
  800. package/src/evals/expect.ts +1 -1
  801. package/src/evals/judge.ts +1 -1
  802. package/src/evals/reporters.ts +8 -9
  803. package/src/evals/run-facts.ts +2 -2
  804. package/src/evals.ts +7 -10
  805. package/src/extensions/cursor-cloud-agents/extension.ts +1 -1
  806. package/src/extensions/cursor-cloud-agents/lib/backend.ts +3 -3
  807. package/src/extensions/cursor-cloud-agents/lib/fleet.ts +1 -1
  808. package/src/extensions/cursor-cloud-agents/lib/repos.ts +3 -3
  809. package/src/extensions/cursor-cloud-agents/lib/transcript.ts +3 -4
  810. package/src/extensions/cursor-cloud-agents/tools/list.ts +1 -1
  811. package/src/extensions/improve/skills/yourself.ts +1 -1
  812. package/src/extensions/slack-communication/evals/harness.ts +728 -0
  813. package/src/extensions/slack-communication/evals/slack-communication.eval.ts +953 -0
  814. package/src/extensions/slack-communication/evals/slack-placeholder.eval.ts +194 -0
  815. package/src/extensions/slack-communication/extension.ts +45 -0
  816. package/src/extensions/slack-communication/skills/slack-voice.ts +59 -0
  817. package/src/extensions/slack-communication/tools/delete-message.ts +34 -0
  818. package/src/extensions/slack-communication/tools/edit-message.ts +42 -0
  819. package/src/extensions/slack-communication/tools/post-card.ts +28 -0
  820. package/src/extensions/slack-communication/tools/post-file.ts +85 -0
  821. package/src/extensions/slack-communication/tools/post-update.ts +41 -0
  822. package/src/extensions/slack-communication/tools/react.ts +33 -0
  823. package/src/extensions/slack-communication/tools/set-status.ts +21 -0
  824. package/src/extensions.ts +2 -6
  825. package/src/files-backends/cursor-hosted.ts +502 -98
  826. package/src/files-backends/local-fs.ts +1 -1
  827. package/src/files.ts +15 -0
  828. package/src/filesystem.ts +16 -18
  829. package/src/index.ts +4 -39
  830. package/src/internal/advertise-tools.ts +6 -6
  831. package/src/internal/approval-gate.ts +1 -1
  832. package/src/internal/artifacts-store.ts +3 -3
  833. package/src/internal/as-of.ts +2 -2
  834. package/src/internal/authored-alias-hooks.ts +32 -0
  835. package/src/internal/authored-loaders.ts +25 -2
  836. package/src/internal/builtin-tools/reminders.ts +2 -2
  837. package/src/internal/chat-client.ts +5 -5
  838. package/src/internal/cli-ax.ts +85 -16
  839. package/src/internal/cli-bitbucket.ts +11 -11
  840. package/src/internal/cli-convert-automation.ts +2 -2
  841. package/src/internal/cli-cursor.ts +5 -16
  842. package/src/internal/cli-deploy.ts +389 -104
  843. package/src/internal/cli-docs.ts +5 -5
  844. package/src/internal/cli-github.ts +16 -19
  845. package/src/internal/cli-gitlab.ts +11 -11
  846. package/src/internal/cli-manifest.ts +1 -1
  847. package/src/internal/cli-mcp-oauth.ts +5 -7
  848. package/src/internal/cli-mcp.ts +3 -3
  849. package/src/internal/cli-skills.ts +2 -2
  850. package/src/internal/cli-slack.ts +5 -5
  851. package/src/internal/cloud-turn-cost.ts +1 -1
  852. package/src/internal/continuation-channel.ts +2 -1
  853. package/src/internal/continuation-identity.ts +23 -11
  854. package/src/internal/conversation-mirror.ts +36 -3
  855. package/src/internal/convert-automation/convert-workflow.ts +27 -27
  856. package/src/internal/convert-automation/types.ts +9 -0
  857. package/src/internal/cursor/account-mcp.ts +48 -31
  858. package/src/internal/cursor/backend-client.ts +28 -17
  859. package/src/internal/cursor/credentials.ts +1 -1
  860. package/src/internal/cursor/hosted-store-secrets.ts +34 -0
  861. package/src/internal/cursor-account-mcp-auth.ts +9 -9
  862. package/src/internal/cursor-deployment-relay.ts +10 -10
  863. package/src/internal/cursor-event-relay.ts +10 -10
  864. package/src/internal/cursor-relay-core.ts +2 -2
  865. package/src/internal/deploy-client.ts +266 -24
  866. package/src/internal/deploy-manifest.ts +46 -8
  867. package/src/internal/discovery/agent-config.ts +34 -0
  868. package/src/internal/discovery/agent.ts +15 -13
  869. package/src/internal/discovery/channels.ts +4 -4
  870. package/src/internal/discovery/connections.ts +4 -4
  871. package/src/internal/discovery/cursor-plugin.ts +12 -12
  872. package/src/internal/discovery/extension-overlay.ts +3 -21
  873. package/src/internal/discovery/extensions.ts +8 -32
  874. package/src/internal/discovery/info.ts +12 -22
  875. package/src/internal/discovery/instructions.ts +1 -1
  876. package/src/internal/discovery/modules.ts +0 -1
  877. package/src/internal/discovery/project.ts +4 -20
  878. package/src/internal/discovery/services.ts +1 -1
  879. package/src/internal/discovery/tools.ts +1 -1
  880. package/src/internal/docs-site.ts +2 -2
  881. package/src/internal/env-file.ts +2 -2
  882. package/src/internal/eval-run-store.ts +7 -9
  883. package/src/internal/eval-runner.ts +20 -21
  884. package/src/internal/evals-client.ts +6 -6
  885. package/src/internal/event-log.ts +10 -10
  886. package/src/internal/event-mapper.ts +37 -2
  887. package/src/internal/filesystem/format.ts +11 -12
  888. package/src/internal/filesystem/scratch.ts +3 -3
  889. package/src/internal/filesystem/tools.ts +6 -8
  890. package/src/internal/filesystem/walk.ts +1 -1
  891. package/src/internal/framework-file-storage.ts +108 -9
  892. package/src/internal/framework-storage-selection.ts +4 -14
  893. package/src/internal/github-fanout.ts +4 -4
  894. package/src/internal/guest-network.ts +4 -4
  895. package/src/internal/host-files.ts +1 -1
  896. package/src/internal/host-kv.ts +2 -2
  897. package/src/internal/hosted-admission-adapter.ts +2 -0
  898. package/src/internal/hosted-catch-protocol.ts +3 -5
  899. package/src/internal/hosted-catch.ts +1 -1
  900. package/src/internal/hosted-delivery-protocol.ts +111 -13
  901. package/src/internal/hosted-delivery.ts +286 -81
  902. package/src/internal/hosted-execution-diag.ts +3 -3
  903. package/src/internal/hosted-execution-latency.ts +334 -0
  904. package/src/internal/hosting.ts +5 -6
  905. package/src/internal/http-channel-define.ts +27 -0
  906. package/src/internal/http-channel.ts +3 -4
  907. package/src/internal/http-control-plane-session.ts +24 -11
  908. package/src/internal/incoming-headers-to-fetch.ts +54 -0
  909. package/src/internal/init-interview.ts +7 -7
  910. package/src/internal/init-project.ts +14 -16
  911. package/src/internal/init-scaffold.ts +2 -3
  912. package/src/internal/inline-stdio-mcp.ts +2 -2
  913. package/src/internal/install-cursor-skills.ts +49 -16
  914. package/src/internal/json-schema.ts +1 -1
  915. package/src/internal/local-control-plane.ts +4 -5
  916. package/src/internal/local-env.ts +3 -3
  917. package/src/internal/log-ring.ts +1 -1
  918. package/src/internal/logs-client.ts +1 -1
  919. package/src/internal/mcp-endpoint.ts +10 -10
  920. package/src/internal/mcp-host.ts +9 -9
  921. package/src/internal/mcp-oauth-on-demand.ts +3 -3
  922. package/src/internal/mcp-oauth.ts +5 -5
  923. package/src/internal/net.ts +2 -2
  924. package/src/internal/otel/config.ts +3 -3
  925. package/src/internal/otel/runtime.ts +14 -14
  926. package/src/internal/peer-connections.ts +2 -2
  927. package/src/internal/platform-schedule-sync.ts +1 -1
  928. package/src/internal/platform-timers.ts +1 -1
  929. package/src/internal/playground/static.ts +2 -2
  930. package/src/internal/playground/toolchain.ts +2 -2
  931. package/src/internal/playground-proxy.ts +3 -3
  932. package/src/internal/process-memory-telemetry.ts +1 -1
  933. package/src/internal/reminder-runner.ts +8 -10
  934. package/src/internal/reminder-store.ts +1 -1
  935. package/src/internal/request-error-status.ts +9 -0
  936. package/src/internal/resolved-connections.ts +8 -8
  937. package/src/internal/result-output.ts +62 -5
  938. package/src/internal/router.ts +4 -4
  939. package/src/internal/run-client.ts +3 -3
  940. package/src/internal/schedule-runner.ts +6 -6
  941. package/src/internal/scm/pr-url.ts +11 -2
  942. package/src/internal/sdk-runner.ts +15 -29
  943. package/src/internal/serve-restart.ts +1 -1
  944. package/src/internal/server.ts +97 -115
  945. package/src/internal/session-cost.ts +3 -3
  946. package/src/internal/session-engine.ts +517 -445
  947. package/src/internal/session-run-log.ts +4 -6
  948. package/src/internal/session-store.ts +213 -39
  949. package/src/internal/sessions-client.ts +3 -3
  950. package/src/internal/slack-thread-key.ts +11 -0
  951. package/src/internal/sleep.ts +1 -1
  952. package/src/internal/storage-coordinator.ts +122 -96
  953. package/src/internal/storage-roles.ts +4 -9
  954. package/src/internal/storage.ts +1 -0
  955. package/src/internal/store-mirror.ts +4 -4
  956. package/src/internal/terminal-style.ts +2 -2
  957. package/src/internal/tool-result.ts +3 -3
  958. package/src/internal/trajectory.ts +7 -7
  959. package/src/internal/turn-governor.ts +2 -2
  960. package/src/internal/turn-outbox.ts +1 -1
  961. package/src/internal/update-check.ts +2 -2
  962. package/src/internal/v2-hosting.ts +14 -0
  963. package/src/internal/workspace.ts +17 -17
  964. package/src/kv/memory-kv.ts +9 -7
  965. package/src/kv.ts +4 -7
  966. package/src/otel-public.ts +24 -0
  967. package/src/otel.ts +7 -2
  968. package/src/prompt.ts +1 -1
  969. package/src/result.ts +10 -8
  970. package/src/storage-backends/cursor-hosted-v2.ts +6 -9
  971. package/src/storage-backends/cursor-hosted.ts +6 -60
  972. package/src/storage-backends/file-kv.ts +17 -58
  973. package/src/storage-protocol.ts +3 -17
  974. package/src/storage.ts +32 -108
  975. package/src/types.ts +101 -73
  976. package/templates/agentic-owners/agent/channels/github.ts +3 -6
  977. package/templates/agentic-owners/agent/lib/github.ts +5 -5
  978. package/templates/agentic-owners/agent/lib/owners/decision.ts +13 -10
  979. package/templates/agentic-owners/agent/lib/owners/handles.ts +2 -2
  980. package/templates/agentic-owners/agent/lib/owners/match.ts +3 -3
  981. package/templates/agentic-owners/agent/lib/owners/matching.ts +1 -1
  982. package/templates/agentic-owners/agent/lib/owners/parse.ts +4 -9
  983. package/templates/agentic-owners/agent/lib/owners/prompt.ts +1 -1
  984. package/templates/agentic-owners/agent/lib/review.ts +37 -30
  985. package/templates/agentic-owners/evals/owners.eval.ts +2 -2
  986. package/templates/agentic-owners/package.json +1 -1
  987. package/templates/agents-md/agent/lib/collect.ts +16 -10
  988. package/templates/agents-md/agent/lib/config.ts +1 -1
  989. package/templates/agents-md/agent/tools/apply_agents.ts +10 -8
  990. package/templates/agents-md/package.json +1 -1
  991. package/templates/code-wiki/agent/channels/github.ts +4 -7
  992. package/templates/code-wiki/agent/lib/repos.ts +1 -1
  993. package/templates/code-wiki/agent/tools/apply_wiki.ts +3 -4
  994. package/templates/code-wiki/package.json +1 -1
  995. package/templates/demo/README.md +10 -6
  996. package/templates/demo/agent/channels/github.ts +2 -0
  997. package/templates/demo/agent/channels/queue.ts +6 -2
  998. package/templates/demo/agent/lib/collect.ts +6 -2
  999. package/templates/demo/agent/lib/repos.ts +5 -0
  1000. package/templates/demo/agent/tools/record_demo.ts +1 -1
  1001. package/templates/demo/evals/demo.eval.ts +1 -5
  1002. package/templates/demo/init.json +25 -0
  1003. package/templates/demo/package.json +1 -1
  1004. package/templates/grokbot-agents/package.json +1 -1
  1005. package/templates/pr-autofixer/agent/channels/github.ts +16 -13
  1006. package/templates/pr-autofixer/agent/lib/merge-watch.ts +2 -4
  1007. package/templates/pr-autofixer/agent/lib/repos.ts +2 -2
  1008. package/templates/pr-autofixer/agent/lib/webhook-routing.ts +1 -1
  1009. package/templates/pr-autofixer/package.json +1 -1
  1010. package/templates/security-help/agent/lib/repos.ts +1 -1
  1011. package/templates/security-help/package.json +1 -1
  1012. package/templates/security-reviewer/agent/lib/repos.ts +1 -1
  1013. package/templates/security-reviewer/agent/tools/post_findings.ts +1 -3
  1014. package/templates/security-reviewer/package.json +1 -1
  1015. package/templates/triage/agent/lib/actuate.ts +26 -41
  1016. package/templates/triage/agent/lib/parse-queue-event.ts +2 -1
  1017. package/templates/triage/agent/lib/verify-webhook.ts +10 -5
  1018. package/templates/triage/agent/tools/record_triage.ts +1 -4
  1019. package/templates/triage/package.json +1 -1
  1020. package/dist/ab.d.ts +0 -209
  1021. package/dist/ab.d.ts.map +0 -1
  1022. package/dist/ab.js +0 -246
  1023. package/dist/client.d.ts +0 -14
  1024. package/dist/client.d.ts.map +0 -1
  1025. package/dist/client.js +0 -12
  1026. package/dist/docs/ab.html +0 -80
  1027. package/dist/docs/ab.md +0 -332
  1028. package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
  1029. package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
  1030. package/dist/docs/assets/app.BASKM3M4.js +0 -1
  1031. package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +0 -1
  1032. package/dist/docs/assets/chunks/framework.BCISBCiQ.js +0 -19
  1033. package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
  1034. package/dist/docs/assets/concepts.md.DgEcZOfT.lean.js +0 -1
  1035. package/dist/docs/assets/evals.md.C1ekS3k2.js +0 -85
  1036. package/dist/docs/assets/evals.md.C1ekS3k2.lean.js +0 -1
  1037. package/dist/docs/assets/guides_agent-to-agent.md.BDb0t1QV.js +0 -10
  1038. package/dist/docs/assets/guides_agent-to-agent.md.BDb0t1QV.lean.js +0 -1
  1039. package/dist/docs/assets/guides_grokbot-agents.md.DyV-WArv.js +0 -9
  1040. package/dist/docs/assets/guides_human-in-the-loop.md.By1G2T3_.js +0 -28
  1041. package/dist/docs/assets/guides_human-in-the-loop.md.By1G2T3_.lean.js +0 -1
  1042. package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +0 -4
  1043. package/dist/docs/assets/hillclimbing.md.CpTGTCle.lean.js +0 -1
  1044. package/dist/docs/assets/index.md.BjH1w2ZW.js +0 -5
  1045. package/dist/docs/assets/index.md.BjH1w2ZW.lean.js +0 -1
  1046. package/dist/docs/assets/quickstart.md.DdQOF7Y8.lean.js +0 -1
  1047. package/dist/docs/assets/reference_project-layout.md.DuBu9a96.js +0 -19
  1048. package/dist/docs/assets/reference_result.md.BK5SxDrf.js +0 -19
  1049. package/dist/docs/assets/reference_result.md.BK5SxDrf.lean.js +0 -1
  1050. package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
  1051. package/dist/docs/assets/scaffolding-agents.md.Kctn3OVb.js +0 -1
  1052. package/dist/docs/assets/scaffolding-agents.md.Kctn3OVb.lean.js +0 -1
  1053. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
  1054. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
  1055. package/dist/docs/assets/skills_create-agent.md.Q3h6Je-e.js +0 -8
  1056. package/dist/docs/assets/skills_create-agent.md.Q3h6Je-e.lean.js +0 -1
  1057. package/dist/docs/assets/skills_debug.md.CVjCXMFF.js +0 -1
  1058. package/dist/docs/assets/skills_debug.md.CVjCXMFF.lean.js +0 -1
  1059. package/dist/docs/assets/skills_evals.md.BhovOvrl.js +0 -25
  1060. package/dist/docs/assets/skills_evals.md.BhovOvrl.lean.js +0 -1
  1061. package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.js +0 -1
  1062. package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.lean.js +0 -1
  1063. package/dist/docs/assets/skills_github.md.hgFX_oKY.js +0 -16
  1064. package/dist/docs/assets/skills_github.md.hgFX_oKY.lean.js +0 -1
  1065. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +0 -7
  1066. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +0 -1
  1067. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
  1068. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
  1069. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +0 -18
  1070. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +0 -1
  1071. package/dist/docs/assets/skills_otel.md.B5Ddv1xH.js +0 -8
  1072. package/dist/docs/assets/skills_otel.md.B5Ddv1xH.lean.js +0 -1
  1073. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +0 -20
  1074. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +0 -1
  1075. package/dist/docs/assets/storage.md.BOHeqk2M.js +0 -30
  1076. package/dist/docs/assets/storage.md.BOHeqk2M.lean.js +0 -1
  1077. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +0 -2
  1078. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +0 -1
  1079. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +0 -2
  1080. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +0 -1
  1081. package/dist/docs/assets/templates_demo.md.BeQX9V3H.js +0 -4
  1082. package/dist/docs/assets/templates_demo.md.BeQX9V3H.lean.js +0 -1
  1083. package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.js +0 -3
  1084. package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.lean.js +0 -1
  1085. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +0 -4
  1086. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +0 -1
  1087. package/dist/docs/concepts.html +0 -27
  1088. package/dist/docs/concepts.md +0 -168
  1089. package/dist/docs/design/filesystem.md +0 -376
  1090. package/dist/docs/design/runtime-abstraction.md +0 -1756
  1091. package/dist/docs/guides/human-in-the-loop.html +0 -54
  1092. package/dist/docs/guides/human-in-the-loop.md +0 -126
  1093. package/dist/docs/reference/result.html +0 -45
  1094. package/dist/docs/reference/result.md +0 -89
  1095. package/dist/docs/scaffolding-agents.html +0 -27
  1096. package/dist/docs/scaffolding-agents.md +0 -130
  1097. package/dist/docs/skills/ab.html +0 -52
  1098. package/dist/docs/skills/ab.md +0 -50
  1099. package/dist/docs/skills/create-agent.html +0 -34
  1100. package/dist/docs/skills/create-agent.md +0 -160
  1101. package/dist/docs/skills/debug.html +0 -27
  1102. package/dist/docs/skills/debug.md +0 -36
  1103. package/dist/docs/skills/evals.html +0 -51
  1104. package/dist/docs/skills/evals.md +0 -99
  1105. package/dist/docs/skills/framework-map.html +0 -27
  1106. package/dist/docs/skills/framework-map.md +0 -100
  1107. package/dist/docs/skills/github.html +0 -42
  1108. package/dist/docs/skills/github.md +0 -93
  1109. package/dist/docs/skills/hillclimb.html +0 -33
  1110. package/dist/docs/skills/hillclimb.md +0 -55
  1111. package/dist/docs/skills/index.html +0 -27
  1112. package/dist/docs/skills/index.md +0 -21
  1113. package/dist/docs/skills/mcp-auth.html +0 -44
  1114. package/dist/docs/skills/mcp-auth.md +0 -76
  1115. package/dist/docs/skills/otel.html +0 -34
  1116. package/dist/docs/skills/otel.md +0 -53
  1117. package/dist/docs/skills/setup-slack.html +0 -46
  1118. package/dist/docs/skills/setup-slack.md +0 -141
  1119. package/dist/docs/storage.html +0 -56
  1120. package/dist/docs/storage.md +0 -176
  1121. package/dist/docs/templates/agents-md.html +0 -28
  1122. package/dist/docs/templates/agents-md.md +0 -105
  1123. package/dist/docs/templates/code-wiki.html +0 -28
  1124. package/dist/docs/templates/code-wiki.md +0 -91
  1125. package/dist/docs/templates/demo.html +0 -30
  1126. package/dist/docs/templates/demo.md +0 -80
  1127. package/dist/docs/templates/grokbot-agents.html +0 -29
  1128. package/dist/docs/templates/grokbot-agents.md +0 -48
  1129. package/dist/docs/templates/security-help.html +0 -30
  1130. package/dist/docs/templates/security-help.md +0 -65
  1131. package/dist/internal/ab-collector.d.ts +0 -44
  1132. package/dist/internal/ab-collector.d.ts.map +0 -1
  1133. package/dist/internal/ab-collector.js +0 -142
  1134. package/dist/internal/ab-fold.d.ts +0 -36
  1135. package/dist/internal/ab-fold.d.ts.map +0 -1
  1136. package/dist/internal/ab-fold.js +0 -175
  1137. package/dist/internal/ab-snapshot.d.ts +0 -68
  1138. package/dist/internal/ab-snapshot.d.ts.map +0 -1
  1139. package/dist/internal/ab-snapshot.js +0 -208
  1140. package/dist/internal/discovery/ab.d.ts +0 -9
  1141. package/dist/internal/discovery/ab.d.ts.map +0 -1
  1142. package/dist/internal/discovery/ab.js +0 -113
  1143. package/dist/internal/tenant-slack/relay.d.ts +0 -75
  1144. package/dist/internal/tenant-slack/relay.d.ts.map +0 -1
  1145. package/dist/internal/tenant-slack/relay.js +0 -148
  1146. package/dist/playground/assets/index-BMDqAeXu.js +0 -67
  1147. package/dist/playground/assets/index-LUgJoWdL.css +0 -1
  1148. package/docs/ab.md +0 -337
  1149. package/docs/concepts.md +0 -173
  1150. package/docs/design/filesystem.md +0 -376
  1151. package/docs/design/runtime-abstraction.md +0 -1756
  1152. package/docs/guides/human-in-the-loop.md +0 -131
  1153. package/docs/reference/result.md +0 -94
  1154. package/docs/scaffolding-agents.md +0 -135
  1155. package/docs/skills/index.md +0 -26
  1156. package/docs/storage.md +0 -181
  1157. package/docs/templates/agents-md.md +0 -110
  1158. package/docs/templates/code-wiki.md +0 -96
  1159. package/docs/templates/demo.md +0 -85
  1160. package/docs/templates/grokbot-agents.md +0 -53
  1161. package/docs/templates/security-help.md +0 -70
  1162. package/skills/ab/SKILL.md +0 -58
  1163. package/src/ab.ts +0 -430
  1164. package/src/client.ts +0 -23
  1165. package/src/internal/ab-collector.ts +0 -200
  1166. package/src/internal/ab-fold.ts +0 -232
  1167. package/src/internal/ab-snapshot.ts +0 -331
  1168. package/src/internal/discovery/ab.ts +0 -131
  1169. package/src/internal/tenant-slack/relay.ts +0 -203
  1170. package/templates/pr-autofixer/agent/storage.ts +0 -7
@@ -8,16 +8,10 @@
8
8
  */
9
9
 
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
11
- import { mkdir, rm, writeFile } from "node:fs/promises";
11
+ import { access, mkdir, rm, writeFile } from "node:fs/promises";
12
12
  import { dirname, join } from "node:path";
13
13
  import type { SDKCustomTool, SDKCustomToolResult } from "@cursor/sdk";
14
14
  import type { Meter } from "@opentelemetry/api";
15
- import {
16
- type ABDefinition,
17
- mergeABInstructions,
18
- resolveABMaxPlaygroundSessions,
19
- resolveABSplit,
20
- } from "../ab.js";
21
15
  import { SLACK_CHANNEL_ID } from "../channels/slack/constants.js";
22
16
  import { materializeSlackNudgeCarrier } from "../channels/slack/nudge-carrier.js";
23
17
  import {
@@ -98,9 +92,6 @@ import {
98
92
  type ToolNeedsApproval,
99
93
  type TurnOutcome,
100
94
  } from "../types.js";
101
- import { ABCollector } from "./ab-collector.js";
102
- import { foldABStream } from "./ab-fold.js";
103
- import { type ABSnapshot, buildABSnapshot } from "./ab-snapshot.js";
104
95
  import {
105
96
  type AdvertiseHostMcp,
106
97
  resolveAdvertisedTools,
@@ -185,7 +176,12 @@ import {
185
176
  SCHEDULE_CHANNEL_PREFIX,
186
177
  } from "./prompt-context.js";
187
178
  import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
188
- import { applyAuthoredResult } from "./result-output.js";
179
+ import {
180
+ addTurnUsage,
181
+ applyAuthoredResult,
182
+ RESULT_REPAIR_BUDGET,
183
+ resultRepairPrompt,
184
+ } from "./result-output.js";
189
185
  import type { AgentRunner, SteerAckOutcome } from "./sdk-runner.js";
190
186
  import { sessionExternalLinks } from "./session-links.js";
191
187
  import { SessionStore } from "./session-store.js";
@@ -252,6 +248,21 @@ export class SessionBusyError extends Error {
252
248
  }
253
249
  }
254
250
 
251
+ /**
252
+ * Hosted enqueue-only admission could not coalesce into an active turn.
253
+ * Distinct from {@link SessionBusyError}: the caller asked not to start work.
254
+ */
255
+ export class HostedEnqueueNotActiveError extends Error {
256
+ constructor(sessionId?: string) {
257
+ super(
258
+ sessionId === undefined
259
+ ? "Hosted enqueue requires an active accepting session"
260
+ : `Hosted enqueue requires an active turn on session ${sessionId}`
261
+ );
262
+ this.name = "HostedEnqueueNotActiveError";
263
+ }
264
+ }
265
+
255
266
  // Defined in auth.js (HTTP/session-store callers import it without this
256
267
  // module); re-exported here because this is its historical public home.
257
268
  export { SessionAuthError } from "./auth.js";
@@ -423,6 +434,12 @@ export interface EngineSendOptions extends SendMessageOptions {
423
434
  * authors cannot choose a session id through the public SendMessageOptions.
424
435
  */
425
436
  hostedSessionId?: string;
437
+ /**
438
+ * Hosted active-guest enqueue: admit only by coalescing into an already
439
+ * running turn. Never creates a session or starts a turn. Private host
440
+ * plumbing — not part of public SendMessageOptions.
441
+ */
442
+ hostedEnqueueOnly?: boolean;
426
443
  }
427
444
 
428
445
  interface CoalescedQueuedTurn {
@@ -438,6 +455,39 @@ interface AdmitTurnOptions {
438
455
  * coalesce drain so asks that arrived during drain are not wiped.
439
456
  */
440
457
  retainCoalesced?: boolean;
458
+ /** See {@link EngineSendOptions.hostedEnqueueOnly}. */
459
+ hostedEnqueueOnly?: boolean;
460
+ }
461
+
462
+ /** Marker that we `git init`'d this shared harness so scaffold is ours to write. */
463
+ const OWNED_HARNESS = join(".agent-serve", "owned-harness");
464
+
465
+ function pathExists(path: string): Promise<boolean> {
466
+ return access(path).then(
467
+ () => true,
468
+ () => false
469
+ );
470
+ }
471
+
472
+ /**
473
+ * Nested dirs get their own git root so the harness does not ripwalk the
474
+ * enclosing checkout. A real `workspaceDir` checkout (already a git root)
475
+ * is left alone.
476
+ */
477
+ async function ownSharedHarness(dir: string): Promise<boolean> {
478
+ if (await pathExists(join(dir, OWNED_HARNESS))) {
479
+ return true;
480
+ }
481
+ if (!(await isNestedInGitRepo(dir))) {
482
+ return false;
483
+ }
484
+ await ensureOwnGitRoot(dir);
485
+ if (await isNestedInGitRepo(dir)) {
486
+ return false;
487
+ }
488
+ await mkdir(join(dir, ".agent-serve"), { recursive: true });
489
+ await writeFile(join(dir, OWNED_HARNESS), "");
490
+ return true;
441
491
  }
442
492
 
443
493
  export class SessionEngine {
@@ -455,8 +505,8 @@ export class SessionEngine {
455
505
  /**
456
506
  * Runtime for `agent/storage.ts` (`defineStorage`), when
457
507
  * authored. All durable state changes funnel through it (session
458
- * records, event chunks, A/B samples/snapshots); the eval run store
459
- * attaches via {@link StorageCoordinator.evalRuns} at serve start.
508
+ * records, event chunks); the eval run store attaches via
509
+ * {@link StorageCoordinator.evalRuns} at serve start.
460
510
  */
461
511
  readonly storage: StorageCoordinator | undefined;
462
512
  /** In-flight lazy restores, deduped per channel + continuation key. */
@@ -464,8 +514,6 @@ export class SessionEngine {
464
514
  string,
465
515
  Promise<SessionRecord | undefined>
466
516
  >();
467
- /** Once-per-process cache for the A/B snapshot backfill (see abSnapshot). */
468
- private restoredAbSnapshot: Promise<ABSnapshot | undefined> | undefined;
469
517
  /** In-flight authored files → Agent Store syncs (see syncToCloudStore). */
470
518
  private readonly cloudSyncs = new Map<CloudSyncSurface, Promise<boolean>>();
471
519
 
@@ -504,6 +552,8 @@ export class SessionEngine {
504
552
  private readonly turnAborts = new Map<string, AbortController>();
505
553
  /** Serializes turn admission per session (latest follow-up wins). */
506
554
  private readonly admissionChains = new Map<string, Promise<unknown>>();
555
+ /** Live turn snapshot so a coalesced Slack wake can repaint on this process. */
556
+ private readonly liveTurns = new Map<string, EventDispatchContext>();
507
557
  /** FIFO turn slots under `concurrency.maxRunningTurns` (unlimited when unset). */
508
558
  private readonly turnGovernor: TurnGovernor;
509
559
  /**
@@ -528,7 +578,6 @@ export class SessionEngine {
528
578
  private probeCursorAccount:
529
579
  | ((connection: string) => Promise<string | undefined>)
530
580
  | undefined;
531
- private readonly abCollector: ABCollector;
532
581
  private readonly otel: OtelCollector | undefined;
533
582
  private readonly otelHost: HostOtelSessionApi;
534
583
  private readonly stopMemoryTelemetry: (() => void) | undefined;
@@ -559,6 +608,8 @@ export class SessionEngine {
559
608
  string,
560
609
  { root: FileSystem; cwd: string }
561
610
  >();
611
+ /** In-flight `prewarmSharedWorkspace`; first turn waits so it lands hot. */
612
+ private sharedWarm: Promise<void> | undefined;
562
613
 
563
614
  constructor(options: SessionEngineOptions) {
564
615
  this.project = options.project;
@@ -587,7 +638,7 @@ export class SessionEngine {
587
638
  );
588
639
  this.outbox = new TurnOutbox(join(options.stateRoot, "outbox"));
589
640
  this.logs = new EventLogStore(
590
- (sessionId) => this.sessions.eventFilePath(sessionId),
641
+ sessionId => this.sessions.eventFilePath(sessionId),
591
642
  (sessionId, error) =>
592
643
  this.logger(
593
644
  `[agent-sdk] failed to persist events for ${sessionId}: ${describeError(error)}`
@@ -639,13 +690,6 @@ export class SessionEngine {
639
690
  config: options.project.artifacts,
640
691
  sink: managedV2Files?.(),
641
692
  });
642
- this.abCollector = new ABCollector(
643
- options.project.abs,
644
- this.logger,
645
- async (sessionId) => (await this.logs.get(sessionId)).snapshot(0),
646
- // Samples flow to the defineStorage `abs` table (no-op without one).
647
- { persistSample: (sample) => this.storage?.abSample(sample) }
648
- );
649
693
  // Peer and Cursor-account transports are symbolic until the serve host
650
694
  // resolves them; the host-side MCP registry starts with the concrete
651
695
  // connections and gains the rest via setResolvedConnections.
@@ -654,7 +698,7 @@ export class SessionEngine {
654
698
  ...options.project.agent.connections,
655
699
  ...(options.project.agent.hostConnections ?? []),
656
700
  ].filter(
657
- (connection) => !isSymbolicConnectionTransport(connection.transport)
701
+ connection => !isSymbolicConnectionTransport(connection.transport)
658
702
  )
659
703
  );
660
704
  const basePlatforms = options.platforms ?? createHostPlatforms();
@@ -707,8 +751,8 @@ export class SessionEngine {
707
751
 
708
752
  private authoredConnection(name: string): DiscoveredConnection | undefined {
709
753
  return (
710
- this.project.agent.connections.find((item) => item.name === name) ??
711
- this.project.agent.hostConnections?.find((item) => item.name === name)
754
+ this.project.agent.connections.find(item => item.name === name) ??
755
+ this.project.agent.hostConnections?.find(item => item.name === name)
712
756
  );
713
757
  }
714
758
 
@@ -777,7 +821,7 @@ export class SessionEngine {
777
821
  */
778
822
  artifactsApi(binding?: { sessionId: string; turnId?: string }): ArtifactsApi {
779
823
  return {
780
- tag: async (input) => {
824
+ tag: async input => {
781
825
  if (binding === undefined) {
782
826
  return this.tagArtifact(input);
783
827
  }
@@ -795,7 +839,7 @@ export class SessionEngine {
795
839
  turnId: input.turnId ?? binding.turnId,
796
840
  });
797
841
  },
798
- list: (filter) => this.artifactsStore.list(filter),
842
+ list: filter => this.artifactsStore.list(filter),
799
843
  };
800
844
  }
801
845
 
@@ -944,11 +988,11 @@ export class SessionEngine {
944
988
 
945
989
  private slackNudgeHostApi(): SlackNudgeHostApi {
946
990
  return {
947
- append: (input) => this.nudgeStore.append(input),
948
- drainFormatted: (continuationKey) =>
991
+ append: input => this.nudgeStore.append(input),
992
+ drainFormatted: continuationKey =>
949
993
  this.nudgeStore.drainFormatted(continuationKey),
950
- clear: (continuationKey) => this.nudgeStore.clear(continuationKey),
951
- hasUndelivered: (continuationKey) =>
994
+ clear: continuationKey => this.nudgeStore.clear(continuationKey),
995
+ hasUndelivered: continuationKey =>
952
996
  this.nudgeStore.hasUndelivered(continuationKey),
953
997
  isDelivered: (continuationKey, sourceTs) =>
954
998
  this.nudgeStore.isDelivered(continuationKey, sourceTs),
@@ -1058,61 +1102,76 @@ export class SessionEngine {
1058
1102
  // Refresh harness cwd when the caller supplies a newer worktree (e.g. PR
1059
1103
  // synchronize). Leave the durable continuation key unchanged.
1060
1104
  let record = existing;
1061
- const refreshWorkspace =
1062
- sendOptions.workspaceDir !== undefined &&
1063
- sendOptions.workspaceDir !== existing.workspaceOverride;
1064
- if (
1065
- refreshWorkspace ||
1066
- sendOptions.workspaceFiles !== undefined ||
1067
- sendOptions.images !== undefined
1068
- ) {
1069
- record = await this.updateRecord(existing.sessionId, (current) => ({
1070
- ...current,
1071
- workspaceOverride: refreshWorkspace
1072
- ? sendOptions.workspaceDir
1073
- : current.workspaceOverride,
1074
- pendingWorkspaceFiles: mergePendingWorkspaceFiles(
1075
- current.pendingWorkspaceFiles,
1076
- sendOptions.workspaceFiles
1077
- ),
1078
- pendingImages: mergePendingImages(
1079
- current.pendingImages,
1080
- sendOptions.images
1081
- ),
1082
- }));
1083
- }
1084
- // Refresh the cloud attach the same way: a follow-up send carries the
1085
- // caller's CURRENT cloud options (e.g. a PR attach re-derived per wake),
1086
- // and the first send's snapshot must not pin this session's turns to a
1087
- // stale repo/prUrl for the session's lifetime.
1088
- if (
1089
- sendOptions.cloud !== undefined &&
1090
- JSON.stringify(sendOptions.cloud) !==
1091
- JSON.stringify(record.cloudOverride)
1092
- ) {
1093
- record = await this.updateRecord(record.sessionId, (current) => ({
1094
- ...current,
1095
- cloudOverride: sendOptions.cloud,
1096
- }));
1097
- }
1098
- // Refresh wake-derived channel state (GitHub headSha / refs) without
1099
- // wiping sticky fields. Null patch values are skipped.
1100
- if (sendOptions.refreshState !== undefined) {
1101
- record = await this.updateRecord(record.sessionId, (current) => ({
1102
- ...current,
1103
- channelState: mergeChannelStateSkipNull(
1104
- current.channelState,
1105
- sendOptions.refreshState
1106
- ),
1107
- }));
1105
+ const enqueueOnly = sendOptions.hostedEnqueueOnly === true;
1106
+ if (!enqueueOnly) {
1107
+ const refreshWorkspace =
1108
+ sendOptions.workspaceDir !== undefined &&
1109
+ sendOptions.workspaceDir !== existing.workspaceOverride;
1110
+ if (
1111
+ refreshWorkspace ||
1112
+ sendOptions.workspaceFiles !== undefined ||
1113
+ sendOptions.images !== undefined
1114
+ ) {
1115
+ record = await this.updateRecord(existing.sessionId, current => ({
1116
+ ...current,
1117
+ workspaceOverride: refreshWorkspace
1118
+ ? sendOptions.workspaceDir
1119
+ : current.workspaceOverride,
1120
+ pendingWorkspaceFiles: mergePendingWorkspaceFiles(
1121
+ current.pendingWorkspaceFiles,
1122
+ sendOptions.workspaceFiles
1123
+ ),
1124
+ pendingImages: mergePendingImages(
1125
+ current.pendingImages,
1126
+ sendOptions.images
1127
+ ),
1128
+ }));
1129
+ }
1130
+ // Refresh the cloud attach the same way: a follow-up send carries the
1131
+ // caller's CURRENT cloud options (e.g. a PR attach re-derived per wake),
1132
+ // and the first send's snapshot must not pin this session's turns to a
1133
+ // stale repo/prUrl for the session's lifetime.
1134
+ if (
1135
+ sendOptions.cloud !== undefined &&
1136
+ JSON.stringify(sendOptions.cloud) !==
1137
+ JSON.stringify(record.cloudOverride)
1138
+ ) {
1139
+ record = await this.updateRecord(record.sessionId, current => ({
1140
+ ...current,
1141
+ cloudOverride: sendOptions.cloud,
1142
+ }));
1143
+ }
1144
+ // Refresh wake-derived channel state (GitHub headSha / refs) without
1145
+ // wiping sticky fields. Null patch values are skipped.
1146
+ if (sendOptions.refreshState !== undefined) {
1147
+ record = await this.updateRecord(record.sessionId, current => ({
1148
+ ...current,
1149
+ channelState: mergeChannelStateSkipNull(
1150
+ current.channelState,
1151
+ sendOptions.refreshState
1152
+ ),
1153
+ }));
1154
+ }
1108
1155
  }
1109
1156
  const since = (await this.logs.get(record.sessionId)).count;
1110
1157
  const coalesced = await this.startTurn(record.sessionId, message, {
1111
- admission: sendOptions.admission ?? "preempt",
1158
+ admission: enqueueOnly
1159
+ ? "coalesce"
1160
+ : (sendOptions.admission ?? "preempt"),
1112
1161
  ...(sendOptions.coalesceSourceTs === undefined
1113
1162
  ? {}
1114
1163
  : { sourceTs: sendOptions.coalesceSourceTs }),
1164
+ ...(enqueueOnly ? { hostedEnqueueOnly: true } : {}),
1115
1165
  });
1166
+ if (enqueueOnly && !coalesced) {
1167
+ throw new HostedEnqueueNotActiveError(record.sessionId);
1168
+ }
1169
+ if (!enqueueOnly && coalesced && sendOptions.refreshState !== undefined) {
1170
+ await this.repaintOnCoalescedRefresh(
1171
+ record.sessionId,
1172
+ sendOptions.refreshState
1173
+ );
1174
+ }
1116
1175
  return this.channelSession(
1117
1176
  record.sessionId,
1118
1177
  record,
@@ -1122,6 +1181,10 @@ export class SessionEngine {
1122
1181
  );
1123
1182
  }
1124
1183
 
1184
+ if (sendOptions.hostedEnqueueOnly === true) {
1185
+ throw new HostedEnqueueNotActiveError(sendOptions.hostedSessionId);
1186
+ }
1187
+
1125
1188
  if (sendOptions.hostedSessionId !== undefined) {
1126
1189
  const collision = await this.getOrRestoreSession(
1127
1190
  sendOptions.hostedSessionId
@@ -1138,7 +1201,7 @@ export class SessionEngine {
1138
1201
  const purpose = sendOptions.purpose === "eval" ? "eval" : "live";
1139
1202
  const frozenAsOf = normalizeAsOf(sendOptions.asOf);
1140
1203
  assertTimeArgs(this.project.agent.tools, frozenAsOf);
1141
- let record: SessionRecord = {
1204
+ const record: SessionRecord = {
1142
1205
  sessionId: sendOptions.hostedSessionId ?? newSessionId(),
1143
1206
  channelId,
1144
1207
  mode: sendOptions.mode ?? "chat",
@@ -1167,7 +1230,6 @@ export class SessionEngine {
1167
1230
  dryRun: record.dryRun === true ? true : undefined,
1168
1231
  },
1169
1232
  });
1170
- record = await this.enrollABs(record);
1171
1233
  const since = (await this.logs.get(record.sessionId)).count;
1172
1234
  await this.startTurn(record.sessionId, message, {
1173
1235
  admission: sendOptions.admission ?? "preempt",
@@ -1191,7 +1253,7 @@ export class SessionEngine {
1191
1253
  const stale = new Error("stale HTTP continuation");
1192
1254
  let previous: string | undefined;
1193
1255
  try {
1194
- await this.updateRecord(sessionId, (record) => {
1256
+ await this.updateRecord(sessionId, record => {
1195
1257
  const expectedChannel =
1196
1258
  record.httpContinuationKey === undefined
1197
1259
  ? record.channelId
@@ -1214,7 +1276,7 @@ export class SessionEngine {
1214
1276
  await this.startTurn(sessionId, message);
1215
1277
  return next;
1216
1278
  } catch (error) {
1217
- await this.updateRecord(sessionId, (record) =>
1279
+ await this.updateRecord(sessionId, record =>
1218
1280
  record.httpContinuationKey === next
1219
1281
  ? { ...record, httpContinuationKey: previous }
1220
1282
  : record
@@ -1241,97 +1303,6 @@ export class SessionEngine {
1241
1303
  return existing !== undefined;
1242
1304
  }
1243
1305
 
1244
- /**
1245
- * Sticky A/B enrollment at session creation — before the first turn, so
1246
- * variants are in the durable stream (and on {@link SessionRecord.abs})
1247
- * ahead of model/instructions work. Failures persist as `variant: null`
1248
- * (sticky skip). Eval harness sessions (`purpose: "eval"`) are never
1249
- * enrolled.
1250
- */
1251
- private async enrollABs(record: SessionRecord): Promise<SessionRecord> {
1252
- if (!this.abCollector.enabled || record.purpose === "eval") {
1253
- return record;
1254
- }
1255
- const sessionInfo = this.sessionInfo(record);
1256
- const abs: Record<string, string | null> = {};
1257
- for (const experiment of this.project.abs) {
1258
- const def = experiment.definition as ABDefinition;
1259
- const variantKeys = Object.keys(def.variants);
1260
- let variant: string | null = null;
1261
- try {
1262
- variant = await resolveABSplit(def.split, {
1263
- agent: { name: this.project.name },
1264
- channel: { id: record.channelId },
1265
- session: sessionInfo,
1266
- experiment: experiment.name,
1267
- variants: variantKeys,
1268
- });
1269
- if (variant !== null && !(variant in def.variants)) {
1270
- throw new Error(
1271
- `split resolved to ${JSON.stringify(variant)}; expected one of ${variantKeys.join(", ")} or null to skip`
1272
- );
1273
- }
1274
- } catch (error) {
1275
- this.logger(
1276
- `[agent-sdk] ab "${experiment.name}" enrollment failed (sticky skip): ${describeError(error)}`
1277
- );
1278
- variant = null;
1279
- }
1280
- abs[experiment.name] = variant;
1281
- await this.appendEvent(record.sessionId, {
1282
- type: "ab.assigned",
1283
- data: { experiment: experiment.name, variant },
1284
- });
1285
- }
1286
- return this.updateRecord(record.sessionId, (current) => ({
1287
- ...current,
1288
- abs,
1289
- }));
1290
- }
1291
-
1292
- /**
1293
- * Ensure {@link SessionRecord.abs} is populated (hydrate from the durable
1294
- * `ab.assigned` stream when missing — e.g. older sessions after upgrade).
1295
- */
1296
- private async ensureAbs(record: SessionRecord): Promise<SessionRecord> {
1297
- if (record.abs !== undefined || record.purpose === "eval") {
1298
- return record;
1299
- }
1300
- if (!this.abCollector.enabled) {
1301
- return record;
1302
- }
1303
- const events = await this.listEvents(record.sessionId, 0);
1304
- const folded = foldABStream(events);
1305
- if (folded.arms.size === 0) {
1306
- return record;
1307
- }
1308
- const abs = Object.fromEntries(folded.arms);
1309
- return this.updateRecord(record.sessionId, (current) => ({
1310
- ...current,
1311
- abs,
1312
- }));
1313
- }
1314
-
1315
- /**
1316
- * Agent config for this session: base project agent plus any per-variant
1317
- * `instructions` overlays from enrolled A/B arms.
1318
- */
1319
- private agentForSession(record: SessionRecord): ResolvedAgent {
1320
- const base = this.project.agent;
1321
- const instructions = mergeABInstructions(
1322
- base.instructions,
1323
- record.abs,
1324
- this.project.abs.map((experiment) => ({
1325
- name: experiment.name,
1326
- definition: experiment.definition as ABDefinition,
1327
- }))
1328
- );
1329
- if (instructions === base.instructions) {
1330
- return base;
1331
- }
1332
- return { ...base, instructions };
1333
- }
1334
-
1335
1306
  /** Look up a session as a channel-scoped handle. */
1336
1307
  async getChannelSession(
1337
1308
  channelId: string,
@@ -1396,6 +1367,53 @@ export class SessionEngine {
1396
1367
  // Turn execution
1397
1368
  // ==========================================================================
1398
1369
 
1370
+ /**
1371
+ * Repaint on the follow-up wake without retargeting the live turn.
1372
+ * Persist already took the refresh; in-flight writes stay on the carrier ts.
1373
+ */
1374
+ private async repaintOnCoalescedRefresh(
1375
+ sessionId: string,
1376
+ patch: JsonValue | undefined
1377
+ ): Promise<void> {
1378
+ const live = this.liveTurns.get(sessionId);
1379
+ if (live === undefined || patch === undefined) {
1380
+ return;
1381
+ }
1382
+ const repaintState =
1383
+ mergeChannelStateSkipNull(live.channelState, patch) ?? live.channelState;
1384
+ const record = await this.sessions.get(sessionId);
1385
+ if (record === undefined) {
1386
+ return;
1387
+ }
1388
+ const handler = this.channelEventHandlersFor(record.channelId)?.[
1389
+ "message.received"
1390
+ ];
1391
+ if (handler === undefined) {
1392
+ return;
1393
+ }
1394
+ await handler(
1395
+ {
1396
+ type: "message.received",
1397
+ data: { text: "" },
1398
+ index: 0,
1399
+ sessionId,
1400
+ at: new Date().toISOString(),
1401
+ },
1402
+ {
1403
+ channelId: record.channelId,
1404
+ state: repaintState,
1405
+ continuationToken: record.continuationKey,
1406
+ setContinuationToken: (token: string | null) =>
1407
+ this.setContinuationToken(sessionId, token),
1408
+ },
1409
+ {
1410
+ session: live.session,
1411
+ host: this.hostForSession(sessionId),
1412
+ artifacts: this.artifactsApi({ sessionId }),
1413
+ }
1414
+ );
1415
+ }
1416
+
1399
1417
  /**
1400
1418
  * Admit a turn for `sessionId`.
1401
1419
  *
@@ -1417,7 +1435,12 @@ export class SessionEngine {
1417
1435
  .catch(() => {})
1418
1436
  .then(async () => {
1419
1437
  // Another server holds the turn: hand the message to it and coalesce.
1438
+ // Enqueue-only must not report coalesced success without a local
1439
+ // enqueue — the outbox drain may never run on this process.
1420
1440
  if (await this.turnLeases.runningElsewhere(sessionId)) {
1441
+ if (options.hostedEnqueueOnly === true) {
1442
+ throw new HostedEnqueueNotActiveError(sessionId);
1443
+ }
1421
1444
  await this.outbox.post(sessionId, { message, options });
1422
1445
  return true;
1423
1446
  }
@@ -1434,7 +1457,7 @@ export class SessionEngine {
1434
1457
  private drainOutbox(sessionId: string): void {
1435
1458
  void this.outbox
1436
1459
  .takeAll(sessionId)
1437
- .then((items) => {
1460
+ .then(items => {
1438
1461
  for (const item of items) {
1439
1462
  void this.startTurn(sessionId, item.message, item.options).catch(
1440
1463
  () => {}
@@ -1448,7 +1471,7 @@ export class SessionEngine {
1448
1471
  const queue = this.coalesceQueues.get(sessionId) ?? [];
1449
1472
  if (
1450
1473
  item.sourceTs !== undefined &&
1451
- queue.some((entry) => entry.sourceTs === item.sourceTs)
1474
+ queue.some(entry => entry.sourceTs === item.sourceTs)
1452
1475
  ) {
1453
1476
  return;
1454
1477
  }
@@ -1529,7 +1552,7 @@ export class SessionEngine {
1529
1552
  }
1530
1553
  const parts = [
1531
1554
  "<slack_followups>",
1532
- `ANSWER-EACH: ${items.length} asks arrived while you were busy. Address each in order; keep replies compact.`,
1555
+ `${items.length} asks arrived while you were busy.`,
1533
1556
  "",
1534
1557
  ];
1535
1558
  for (let i = 0; i < items.length; i++) {
@@ -1623,11 +1646,21 @@ export class SessionEngine {
1623
1646
  // enqueue: `drainCoalescedFollowups` reads only this process's queue, so
1624
1647
  // the shared nudge store is the carrier. Not redundant with `acquire`
1625
1648
  // below — this returns before preempt's `clearCoalesced` drops the queue.
1649
+ // Enqueue-only cannot claim coalesced here: nothing joined a local turn.
1626
1650
  if (await this.turnLeases.runningElsewhere(sessionId)) {
1651
+ if (options.hostedEnqueueOnly === true) {
1652
+ throw new HostedEnqueueNotActiveError(sessionId);
1653
+ }
1627
1654
  this.logger(`[session] coalesce; another server owns ${sessionId}`);
1628
1655
  return true;
1629
1656
  }
1630
1657
 
1658
+ // Enqueue-only must never start a turn (or preempt/interrupt). Steer and
1659
+ // coalesce above already returned true when they absorbed the message.
1660
+ if (options.hostedEnqueueOnly === true) {
1661
+ throw new HostedEnqueueNotActiveError(sessionId);
1662
+ }
1663
+
1631
1664
  // Interrupt any turn in flight and wait for it to settle so the SDK run is
1632
1665
  // terminal before this turn's send (the follow-up also force-expires as a
1633
1666
  // belt-and-suspenders — see buildTurnRequest). Drain-resume skips interrupt:
@@ -1656,12 +1689,10 @@ export class SessionEngine {
1656
1689
 
1657
1690
  let lifecycleInstalled = false;
1658
1691
  try {
1659
- let record = await this.updateRecord(sessionId, (current) => ({
1692
+ const record = await this.updateRecord(sessionId, current => ({
1660
1693
  ...current,
1661
1694
  turnCount: current.turnCount + 1,
1662
1695
  }));
1663
- // Arms must be on the record before tools/instructions see SessionInfo.
1664
- record = await this.ensureAbs(record);
1665
1696
  const turnId = `turn_${record.turnCount}`;
1666
1697
  const isFirstTurn = record.turnCount === 1;
1667
1698
 
@@ -1704,6 +1735,7 @@ export class SessionEngine {
1704
1735
  };
1705
1736
  } finally {
1706
1737
  clearInterval(poll);
1738
+ this.liveTurns.delete(sessionId);
1707
1739
  }
1708
1740
  this.lastOutcomes.set(sessionId, outcome);
1709
1741
  const wasCurrent = this.activeTurns.get(sessionId) === lifecycle;
@@ -1713,14 +1745,19 @@ export class SessionEngine {
1713
1745
  if (this.turnAborts.get(sessionId) === abort) {
1714
1746
  this.turnAborts.delete(sessionId);
1715
1747
  }
1716
- if (wasCurrent && !abort.signal.aborted) {
1717
- const drain = this.drainCoalescedFollowups(sessionId).catch(
1718
- (error) => {
1719
- this.logger(
1720
- `[session] coalesce drain failed for ${sessionId}: ${describeError(error)}`
1721
- );
1722
- }
1723
- );
1748
+ // Failed/cancelled owners must not start a coalesced successor.
1749
+ // Hosted execute would then 503 and Temporal/FIFO would re-run the
1750
+ // same follow-ups as full deliveries.
1751
+ if (
1752
+ wasCurrent &&
1753
+ !abort.signal.aborted &&
1754
+ outcome.status === "finished"
1755
+ ) {
1756
+ const drain = this.drainCoalescedFollowups(sessionId).catch(error => {
1757
+ this.logger(
1758
+ `[session] coalesce drain failed for ${sessionId}: ${describeError(error)}`
1759
+ );
1760
+ });
1724
1761
  this.coalesceDrains.set(sessionId, drain);
1725
1762
  try {
1726
1763
  await drain;
@@ -1980,7 +2017,7 @@ export class SessionEngine {
1980
2017
  if (turn === undefined) {
1981
2018
  return tools;
1982
2019
  }
1983
- return tools.map((tool) => {
2020
+ return tools.map(tool => {
1984
2021
  const execute = tool.definition.execute;
1985
2022
  if (typeof execute !== "function") {
1986
2023
  return tool;
@@ -2157,6 +2194,13 @@ export class SessionEngine {
2157
2194
  * Best effort — warming is an optimization, and a turn rebuilds on its own.
2158
2195
  */
2159
2196
  async prewarmSharedWorkspace(): Promise<void> {
2197
+ if (this.sharedWarm === undefined) {
2198
+ this.sharedWarm = this.warmSharedWorkspace();
2199
+ }
2200
+ await this.sharedWarm;
2201
+ }
2202
+
2203
+ private async warmSharedWorkspace(): Promise<void> {
2160
2204
  const agent = this.project.agent;
2161
2205
  const workspaceDir = agent.local?.workspaceDir;
2162
2206
  if (
@@ -2169,6 +2213,15 @@ export class SessionEngine {
2169
2213
  }
2170
2214
  const startedAt = Date.now();
2171
2215
  try {
2216
+ await mkdir(workspaceDir, { recursive: true });
2217
+ if (await ownSharedHarness(workspaceDir)) {
2218
+ await materializeWorkspace({
2219
+ agent,
2220
+ workspaceDir,
2221
+ seed: true,
2222
+ stateRoot: this.stateRoot,
2223
+ });
2224
+ }
2172
2225
  const harness = resolveHostHarnessToolOptions(agent.allowedTools);
2173
2226
  const outcome = await this.runner.prewarm({
2174
2227
  workspaceDir,
@@ -2182,7 +2235,10 @@ export class SessionEngine {
2182
2235
  // warmed without an identity; the per-send flag still has to match
2183
2236
  // the turns' requests or the warmed executor is one no turn asks for.
2184
2237
  mcpServers: this.buildMcpServers("local"),
2185
- ...(this.hasAttachedAuthedConnections()
2238
+ ...(this.hasAttachedAuthedConnections() ||
2239
+ this.project.agent.connections.some(connection =>
2240
+ isCursorAccountTransport(connection.transport)
2241
+ )
2186
2242
  ? { perSendMcpServers: true }
2187
2243
  : {}),
2188
2244
  subagents: buildRunnerSubagents(agent),
@@ -2226,6 +2282,7 @@ export class SessionEngine {
2226
2282
  channelState: structuredClone(turnChannelState),
2227
2283
  session: this.sessionInfo(record),
2228
2284
  };
2285
+ this.liveTurns.set(sessionId, eventContext);
2229
2286
  // Hold the open log so tool events append synchronously. Fire-and-forget
2230
2287
  // `appendEvent` races parallel tool completions and delays the live stream
2231
2288
  // until the next await tick — often after *all* parallel tools finish.
@@ -2243,7 +2300,7 @@ export class SessionEngine {
2243
2300
  // Read by closure, so the mapper still sees it while draining after the
2244
2301
  // registry entry below is gone.
2245
2302
  const stubbed = new Set<string>();
2246
- const mapper = new TurnEventMapper(emit, (callId) => stubbed.has(callId));
2303
+ const mapper = new TurnEventMapper(emit, callId => stubbed.has(callId));
2247
2304
 
2248
2305
  // Take a turn slot before any work happens. When every slot is busy the
2249
2306
  // turn waits FIFO — durable `turn.queued` marks the wait — and a
@@ -2252,7 +2309,7 @@ export class SessionEngine {
2252
2309
  const permit = await this.turnGovernor.acquire({
2253
2310
  sessionId,
2254
2311
  signal,
2255
- onQueued: (position) => {
2312
+ onQueued: position => {
2256
2313
  const maxRunningTurns = this.turnGovernor.maxRunningTurns ?? 0;
2257
2314
  emit({ type: "turn.queued", data: { position, maxRunningTurns } });
2258
2315
  this.logger(
@@ -2268,13 +2325,17 @@ export class SessionEngine {
2268
2325
  } else {
2269
2326
  emit({ type: "turn.started", data: {} });
2270
2327
  try {
2328
+ if (
2329
+ record.workspaceOverride === undefined &&
2330
+ this.project.agent.local?.workspaceDir !== undefined
2331
+ ) {
2332
+ await this.prewarmSharedWorkspace();
2333
+ }
2271
2334
  // Scaffold agent files into the session workspace even when the harness
2272
- // cwd is overridden (e.g. a PR worktree). A/B variant instruction
2273
- // overlays are applied via agentForSession.
2274
- const agent = this.agentForSession(record);
2335
+ // cwd is overridden (e.g. a PR worktree).
2275
2336
  if (!this.hasRootOverride()) {
2276
2337
  await materializeWorkspace({
2277
- agent,
2338
+ agent: this.project.agent,
2278
2339
  workspaceDir,
2279
2340
  seed: isFirstTurn,
2280
2341
  stateRoot: this.stateRoot,
@@ -2296,7 +2357,7 @@ export class SessionEngine {
2296
2357
  const pendingFiles = record.pendingWorkspaceFiles;
2297
2358
  const pendingImages = record.pendingImages;
2298
2359
  const runtime = resolveSessionRuntime({
2299
- agentRuntime: agent.runtime,
2360
+ agentRuntime: this.project.agent.runtime,
2300
2361
  cloudOverride: record.cloudOverride,
2301
2362
  });
2302
2363
  const hasPendingFiles =
@@ -2314,7 +2375,7 @@ export class SessionEngine {
2314
2375
  (hasPendingFiles && runtime !== "cloud") ||
2315
2376
  (pendingImages !== undefined && pendingImages.length > 0)
2316
2377
  ) {
2317
- await this.updateRecord(sessionId, (current) => ({
2378
+ await this.updateRecord(sessionId, current => ({
2318
2379
  ...current,
2319
2380
  pendingWorkspaceFiles:
2320
2381
  hasPendingFiles &&
@@ -2328,49 +2389,39 @@ export class SessionEngine {
2328
2389
  : current.pendingImages,
2329
2390
  }));
2330
2391
  }
2331
- // The harness only loads the scaffolded AGENTS.md when the session
2332
- // workspace is its own project root. When the harness cwd is borrowed
2333
- // (PR worktree, shared checkout) the scaffold lands elsewhere, and a
2334
- // workspace nested inside a git repo re-roots harness rules at that
2335
- // repo — in both cases deliver instructions inline on the first turn.
2336
- const instructionsInvisibleToHarness =
2337
- isFirstTurn &&
2338
- (this.hasBorrowedWorkspace(record) ||
2339
- (await isNestedInGitRepo(harnessCwd)));
2392
+ const onUpdate: RunnerTurnRequest["onUpdate"] = async update => {
2393
+ const turn = this.turnRoots.get(sessionId);
2394
+ if (turn !== undefined) {
2395
+ update = await applyWebScratchUpdate({
2396
+ cwd: turn.cwd,
2397
+ root: turn.root,
2398
+ update,
2399
+ });
2400
+ }
2401
+ mapper.handleUpdate(update);
2402
+ // Yield so the HTTP NDJSON writer can flush tool start/result
2403
+ // events while sibling parallel tools are still executing.
2404
+ if (
2405
+ update.type === "tool-call-started" ||
2406
+ update.type === "tool-call-completed" ||
2407
+ // Nested subagent progress (newer SDKs); string check keeps
2408
+ // typecheck green against older published `@cursor/sdk` pins.
2409
+ (update as { type: string }).type === "tool-call-delta"
2410
+ ) {
2411
+ // Same boundary the carrier hook runs on, so a drain is visible
2412
+ // by the time this fires.
2413
+ await this.emitDeliveredNudges(record, emit);
2414
+ await yieldEventLoop();
2415
+ }
2416
+ };
2340
2417
  const request = await this.buildTurnRequest(
2341
2418
  record,
2342
- agent,
2343
2419
  turnId,
2344
2420
  message,
2345
2421
  isFirstTurn,
2346
- instructionsInvisibleToHarness,
2347
2422
  emit,
2348
2423
  eventContext,
2349
- async (update) => {
2350
- const turn = this.turnRoots.get(sessionId);
2351
- if (turn !== undefined) {
2352
- update = await applyWebScratchUpdate({
2353
- cwd: turn.cwd,
2354
- root: turn.root,
2355
- update,
2356
- });
2357
- }
2358
- mapper.handleUpdate(update);
2359
- // Yield so the HTTP NDJSON writer can flush tool start/result
2360
- // events while sibling parallel tools are still executing.
2361
- if (
2362
- update.type === "tool-call-started" ||
2363
- update.type === "tool-call-completed" ||
2364
- // Nested subagent progress (newer SDKs); string check keeps
2365
- // typecheck green against older published `@cursor/sdk` pins.
2366
- (update as { type: string }).type === "tool-call-delta"
2367
- ) {
2368
- // Same boundary the carrier hook runs on, so a drain is visible
2369
- // by the time this fires.
2370
- await this.emitDeliveredNudges(record, emit);
2371
- await yieldEventLoop();
2372
- }
2373
- },
2424
+ onUpdate,
2374
2425
  signal,
2375
2426
  pendingImages
2376
2427
  );
@@ -2380,6 +2431,20 @@ export class SessionEngine {
2380
2431
  outcome = await this.runTurnExecute(record, turnId, () =>
2381
2432
  this.runner.runTurn(request)
2382
2433
  );
2434
+ // Commit before dropping the turn FS so `ctx.reject` can
2435
+ // re-run the model with tools still mounted.
2436
+ outcome = await this.settleAuthoredResult({
2437
+ record,
2438
+ turnId,
2439
+ emit,
2440
+ eventContext,
2441
+ turnChannelState,
2442
+ harnessCwd,
2443
+ signal,
2444
+ onUpdate,
2445
+ mapper,
2446
+ outcome,
2447
+ });
2383
2448
  } finally {
2384
2449
  this.activeToolContexts.delete(sessionId);
2385
2450
  this.stubbedCallIds.delete(sessionId);
@@ -2409,7 +2474,7 @@ export class SessionEngine {
2409
2474
 
2410
2475
  if (mapper.title !== undefined) {
2411
2476
  const title = mapper.title;
2412
- await this.updateRecord(sessionId, (current) => ({ ...current, title }));
2477
+ await this.updateRecord(sessionId, current => ({ ...current, title }));
2413
2478
  eventContext.session = { ...eventContext.session, title };
2414
2479
  }
2415
2480
 
@@ -2428,32 +2493,6 @@ export class SessionEngine {
2428
2493
  outcome = { ...outcome, cost: finalCost };
2429
2494
  }
2430
2495
 
2431
- const authored = this.project.result;
2432
- if (outcome.status === "finished" && authored !== undefined) {
2433
- const settled = await applyAuthoredResult({
2434
- definition: authored,
2435
- text: finalResult,
2436
- dryRun: record.dryRun === true,
2437
- ctx: {
2438
- session: eventContext.session,
2439
- channelState: turnChannelState,
2440
- host: this.hostForSession(sessionId),
2441
- artifacts: this.artifactsApi({ sessionId, turnId }),
2442
- stateRoot: this.stateRoot,
2443
- workspaceDir: harnessCwd,
2444
- },
2445
- });
2446
- if (!settled.ok) {
2447
- outcome = {
2448
- status: "error",
2449
- result: finalResult,
2450
- errorMessage: `turn output failed: ${settled.message}`,
2451
- usage: finalUsage,
2452
- cost: finalCost,
2453
- };
2454
- }
2455
- }
2456
-
2457
2496
  if (outcome.status === "finished") {
2458
2497
  await this.appendEvent(
2459
2498
  sessionId,
@@ -2523,6 +2562,89 @@ export class SessionEngine {
2523
2562
  };
2524
2563
  }
2525
2564
 
2565
+ /**
2566
+ * Run `defineResult` while the turn FS and tools are still up.
2567
+ * `ctx.reject` re-invokes `runTurn` on this turnId until commit
2568
+ * succeeds, throws, or the repair budget is gone.
2569
+ */
2570
+ private async settleAuthoredResult(args: {
2571
+ record: SessionRecord;
2572
+ turnId: string;
2573
+ emit: (payload: SessionEventPayload) => void;
2574
+ eventContext: EventDispatchContext;
2575
+ turnChannelState: JsonValue;
2576
+ harnessCwd: string;
2577
+ signal: AbortSignal;
2578
+ onUpdate: RunnerTurnRequest["onUpdate"];
2579
+ mapper: TurnEventMapper;
2580
+ outcome: TurnOutcome;
2581
+ }): Promise<TurnOutcome> {
2582
+ const authored = this.project.result;
2583
+ if (args.outcome.status !== "finished" || authored === undefined) {
2584
+ return args.outcome;
2585
+ }
2586
+
2587
+ let outcome = args.outcome;
2588
+ let usage = outcome.usage;
2589
+ let repairs = 0;
2590
+
2591
+ while (true) {
2592
+ const settled = await applyAuthoredResult({
2593
+ definition: authored,
2594
+ text: outcome.result ?? args.mapper.pendingText,
2595
+ dryRun: args.record.dryRun === true,
2596
+ ctx: {
2597
+ session: args.eventContext.session,
2598
+ channelState: args.turnChannelState,
2599
+ host: this.hostForSession(args.record.sessionId),
2600
+ artifacts: this.artifactsApi({
2601
+ sessionId: args.record.sessionId,
2602
+ turnId: args.turnId,
2603
+ }),
2604
+ stateRoot: this.stateRoot,
2605
+ workspaceDir: args.harnessCwd,
2606
+ },
2607
+ });
2608
+ if (settled.ok) {
2609
+ return { ...outcome, result: settled.text, usage };
2610
+ }
2611
+ if (settled.kind === "error" || repairs >= RESULT_REPAIR_BUDGET) {
2612
+ return {
2613
+ status: "error",
2614
+ result: outcome.result,
2615
+ errorMessage: `turn output failed: ${settled.message}`,
2616
+ usage,
2617
+ };
2618
+ }
2619
+ repairs += 1;
2620
+ // Close the rejected stream without posting it (empty `stop`)
2621
+ // so Slack does not append a repair onto that block, and so an
2622
+ // empty repair cannot recommit `lastAssistantText`.
2623
+ args.mapper.abandonPendingText();
2624
+ this.logger(
2625
+ `[session] ${args.record.sessionId} ${args.turnId} result rejected; repairing (${repairs}/${RESULT_REPAIR_BUDGET})`
2626
+ );
2627
+ const repairRequest = await this.buildTurnRequest(
2628
+ args.record,
2629
+ args.turnId,
2630
+ resultRepairPrompt(settled.message),
2631
+ false,
2632
+ args.emit,
2633
+ args.eventContext,
2634
+ args.onUpdate,
2635
+ args.signal
2636
+ );
2637
+ const repaired = await this.runTurnExecute(args.record, args.turnId, () =>
2638
+ this.runner.runTurn(repairRequest)
2639
+ );
2640
+ usage = addTurnUsage(usage, repaired.usage);
2641
+ if (repaired.status !== "finished") {
2642
+ return { ...repaired, usage };
2643
+ }
2644
+ outcome = { ...repaired, usage };
2645
+ }
2646
+ }
2647
+
2526
2648
  /**
2527
2649
  * Sync authored skills onto the Agent Store at `skills/<name>/…` (hosted)
2528
2650
  * or `agent-serve/<agent>/skills/<name>/…` (personal-key local+cloud)
@@ -2615,7 +2737,7 @@ export class SessionEngine {
2615
2737
  sessionId: string,
2616
2738
  pending: NonNullable<SessionRecord["pendingWorkspaceFiles"]>
2617
2739
  ): Promise<void> {
2618
- await this.updateRecord(sessionId, (current) => ({
2740
+ await this.updateRecord(sessionId, current => ({
2619
2741
  ...current,
2620
2742
  pendingWorkspaceFiles:
2621
2743
  current.pendingWorkspaceFiles === pending
@@ -2648,7 +2770,7 @@ export class SessionEngine {
2648
2770
  }
2649
2771
  let sync = run().then(
2650
2772
  () => true,
2651
- (error) => {
2773
+ error => {
2652
2774
  this.logger(
2653
2775
  `[${surface}] ${store.label} sync failed: ${error instanceof Error ? error.message : String(error)}`
2654
2776
  );
@@ -2667,11 +2789,17 @@ export class SessionEngine {
2667
2789
  /**
2668
2790
  * Hosted deployments own the deployment store. Local `serve`/`run` with
2669
2791
  * a personal API key writes into the USER store under `agent-serve/`.
2792
+ * A persistent deployment's version container has no cloud store at all:
2793
+ * its state directory is the durable copy, and its service-account key
2794
+ * must not be mistaken for a personal one.
2670
2795
  */
2671
2796
  private cloudStore(): CloudStoreTarget | undefined {
2672
2797
  const v2Hosting = resolveAgentV2Hosting({
2673
2798
  architecture: this.project.agent.architecture,
2674
2799
  });
2800
+ if (v2Hosting.kind === "cursor-managed-persistent") {
2801
+ return undefined;
2802
+ }
2675
2803
  const deployment = {
2676
2804
  mountPath: DEPLOYMENT_STORE_MOUNT_PATH,
2677
2805
  skillsPrefix: agentStoreKeys.skillsPrefix(),
@@ -2713,17 +2841,16 @@ export class SessionEngine {
2713
2841
 
2714
2842
  private async buildTurnRequest(
2715
2843
  record: SessionRecord,
2716
- agent: ResolvedAgent,
2717
2844
  turnId: string,
2718
2845
  prompt: string,
2719
2846
  isFirstTurn: boolean,
2720
- instructionsInvisibleToHarness: boolean,
2721
2847
  emit: (payload: SessionEventPayload) => void,
2722
2848
  eventContext: EventDispatchContext,
2723
2849
  onUpdate: RunnerTurnRequest["onUpdate"],
2724
2850
  signal: AbortSignal,
2725
2851
  images?: Array<{ data: string; mimeType: string }>
2726
2852
  ): Promise<RunnerTurnRequest> {
2853
+ const agent = this.project.agent;
2727
2854
  // Per-session cloud attach (channel/tool handoff) forces cloud runtime
2728
2855
  // even when the agent defaults to local for chat server tools.
2729
2856
  const runtime = resolveSessionRuntime({
@@ -2758,7 +2885,7 @@ export class SessionEngine {
2758
2885
  // agents already fail discovery; this guards hybrid agents' per-send
2759
2886
  // cloud sessions.
2760
2887
  const perSessionConnection = agent.connections.find(
2761
- (connection) =>
2888
+ connection =>
2762
2889
  connection.advertiseTools === true || connection.auth !== undefined
2763
2890
  );
2764
2891
  if (runtime !== "local" && perSessionConnection !== undefined) {
@@ -2812,7 +2939,7 @@ export class SessionEngine {
2812
2939
  : this.withTurnScratchTools(
2813
2940
  authoredRoot
2814
2941
  ? fileTools
2815
- : fileTools.filter((tool) => tool.name !== "SemanticSearch"),
2942
+ : fileTools.filter(tool => tool.name !== "SemanticSearch"),
2816
2943
  record.sessionId
2817
2944
  );
2818
2945
  let turnPrompt = prompt;
@@ -2888,6 +3015,9 @@ export class SessionEngine {
2888
3015
  }
2889
3016
  }
2890
3017
  } else if (pending !== undefined && Object.keys(pending).length > 0) {
3018
+ this.logger(
3019
+ `[workspace] no cloud store on this hosting; dropping workspaceFiles for session ${record.sessionId}: ${Object.keys(pending).join(", ")}`
3020
+ );
2891
3021
  await this.clearPendingWorkspaceFiles(record.sessionId, pending);
2892
3022
  }
2893
3023
  if (isFirstTurn && hosted) {
@@ -2895,45 +3025,33 @@ export class SessionEngine {
2895
3025
  }
2896
3026
  if (preamble !== "" || sections.length > 0) {
2897
3027
  turnPrompt = [preamble, ...sections, turnPrompt]
2898
- .filter((part) => part !== "")
3028
+ .filter(part => part !== "")
2899
3029
  .join("\n\n");
2900
3030
  }
2901
3031
  } else if (isFirstTurn && runtime === "local" && authoredRoot) {
2902
- // Virtual roots skip materialize, so AGENTS.md never lands on disk.
2903
- // Ship the same preamble the borrowed-cwd local path uses.
2904
- const preamble = buildAgentsMdContent(
2905
- { ...agent, tools: [...agent.tools, ...synthesized] },
2906
- { includeScripts: true }
2907
- );
2908
- const workspaceInfo = `<user_info>\nWorkspace Path: /\n</user_info>`;
2909
- turnPrompt =
2910
- preamble === ""
2911
- ? `${workspaceInfo}\n\n${turnPrompt}`
2912
- : `${workspaceInfo}\n\n${preamble}\n\n${turnPrompt}`;
2913
- } else if (
2914
- isFirstTurn &&
2915
- runtime === "local" &&
2916
- instructionsInvisibleToHarness
2917
- ) {
2918
- // Local workspace whose AGENTS.md the harness will not load. With a
2919
- // borrowed harness cwd, agent tool scripts live only in the durable
2920
- // scaffold dir — embed bodies like cloud. Otherwise the catalog can
2921
- // reference on-disk paths under the harness cwd. Grokbot turns are
2922
- // excluded: their instructions ride the request's `instructions`
2923
- // field into the Sand system prompt instead.
2924
- const includeScripts = this.hasBorrowedWorkspace(record);
2925
- const preamble = buildAgentsMdContent(agent, { includeScripts });
2926
- turnPrompt = `${preamble}\n\n${turnPrompt}`;
3032
+ // The harness reports no path for a root it never mounted.
3033
+ turnPrompt = `<user_info>\nWorkspace Path: /\n</user_info>\n\n${turnPrompt}`;
2927
3034
  }
3035
+ // A virtual root has no scaffold dir either, so its catalog carries the
3036
+ // synthesized file tools and embedded script bodies.
3037
+ const localInstructions =
3038
+ runtime === "local"
3039
+ ? authoredRoot
3040
+ ? buildAgentsMdContent(
3041
+ { ...agent, tools: [...agent.tools, ...synthesized] },
3042
+ { includeScripts: true }
3043
+ )
3044
+ : buildAgentsMdContent(agent, {
3045
+ includeScripts: this.hasBorrowedWorkspace(record),
3046
+ })
3047
+ : undefined;
2928
3048
  return {
2929
3049
  sessionId: record.sessionId,
2930
3050
  ...(record.sdkAgentId === undefined
2931
3051
  ? {}
2932
3052
  : { sdkAgentId: record.sdkAgentId }),
2933
3053
  workspaceDir: this.harnessCwd(record),
2934
- sandbox: authoredRoot
2935
- ? false
2936
- : this.project.agent.local?.sandbox === true,
3054
+ sandbox: authoredRoot ? false : agent.local?.sandbox === true,
2937
3055
  ...(runtime === "local" && harnessTools !== undefined
2938
3056
  ? {
2939
3057
  ...(harnessTools.tools === undefined
@@ -2952,34 +3070,35 @@ export class SessionEngine {
2952
3070
  runtime,
2953
3071
  agentName: agent.name,
2954
3072
  ...(mergedCloud === undefined ? {} : { cloud: mergedCloud }),
2955
- // The hosted Grok Bot harness reads no workspace AGENTS.md: grokbot
2956
- // turns carry the composed instructions into the hosted session,
2957
- // which surfaces them in the Sand system prompt. The box never sees
2958
- // the local session workspace, so agent-tool script bodies are
2959
- // always embedded same rule as the cloud first-prompt preamble.
3073
+ // Local turns send the composed instructions as the harness system
3074
+ // prompt; grokbot turns carry them into the hosted session, which
3075
+ // surfaces them in the Sand system prompt. Cloud turns inline them into
3076
+ // the first prompt above instead. Script bodies are embedded whenever
3077
+ // the harness cannot reach the scaffold dir: always for grokbot (the
3078
+ // box never sees the session workspace) and for a borrowed local cwd
3079
+ // (PR worktree, shared checkout); otherwise the catalog references the
3080
+ // on-disk paths under the harness cwd.
2960
3081
  instructions:
2961
3082
  runtime === "grokbot"
2962
3083
  ? buildAgentsMdContent(agent, { includeScripts: true })
2963
- : undefined,
3084
+ : localInstructions,
2964
3085
  ...(runtime === "cloud" && !isCursorHostedFilesAvailable()
2965
3086
  ? { agentServeAgent: this.project.name }
2966
3087
  : {}),
2967
3088
  customTools:
2968
3089
  runtime === "local"
2969
- ? await this.buildCustomTools(
2970
- record,
2971
- agent,
2972
- turnId,
2973
- emit,
2974
- synthesized
2975
- )
3090
+ ? await this.buildCustomTools(record, turnId, emit, synthesized)
2976
3091
  : {},
2977
3092
  mcpServers: this.buildMcpServers(
2978
3093
  runtime,
2979
3094
  record.sessionId,
2980
3095
  await this.evaluateConnectionAuth(record)
2981
3096
  ),
2982
- ...(runtime === "local" && this.hasAttachedAuthedConnections()
3097
+ ...(runtime === "local" &&
3098
+ (this.hasAttachedAuthedConnections() ||
3099
+ this.project.agent.connections.some(connection =>
3100
+ isCursorAccountTransport(connection.transport)
3101
+ ))
2983
3102
  ? { perSendMcpServers: true }
2984
3103
  : {}),
2985
3104
  subagents: buildRunnerSubagents(agent),
@@ -2988,14 +3107,14 @@ export class SessionEngine {
2988
3107
  // Local follow-ups expire any lingering active run so a preempted turn
2989
3108
  // (or one orphaned by a crashed process) never blocks this send.
2990
3109
  forceExpireActiveRun: runtime === "local" && !isFirstTurn,
2991
- onRequestId: (requestId) => {
3110
+ onRequestId: requestId => {
2992
3111
  emit({ type: "turn.bound", data: { requestId } });
2993
3112
  },
2994
- onSdkAgentId: async (sdkAgentId) => {
3113
+ onSdkAgentId: async sdkAgentId => {
2995
3114
  if (record.sdkAgentId === sdkAgentId) {
2996
3115
  return;
2997
3116
  }
2998
- await this.updateRecord(record.sessionId, (current) => ({
3117
+ await this.updateRecord(record.sessionId, current => ({
2999
3118
  ...current,
3000
3119
  sdkAgentId,
3001
3120
  }));
@@ -3097,12 +3216,12 @@ export class SessionEngine {
3097
3216
  // attached MCP server (each tool appears exactly once).
3098
3217
  const advertisedNames = new Set(
3099
3218
  this.project.agent.connections
3100
- .filter((connection) => connection.advertiseTools === true)
3101
- .map((connection) => connection.name)
3219
+ .filter(connection => connection.advertiseTools === true)
3220
+ .map(connection => connection.name)
3102
3221
  );
3103
3222
  const hostConnectionNames = new Set(
3104
3223
  (this.project.agent.hostConnections ?? []).map(
3105
- (connection) => connection.name
3224
+ connection => connection.name
3106
3225
  )
3107
3226
  );
3108
3227
  const bridgedNames = new Set(
@@ -3116,7 +3235,7 @@ export class SessionEngine {
3116
3235
  assertCloudCanHonorAccountServersFilters({
3117
3236
  runtime,
3118
3237
  resolvedConnections: this.resolvedConnections.filter(
3119
- (resolved) =>
3238
+ resolved =>
3120
3239
  !advertisedNames.has(resolved.name) &&
3121
3240
  !hostConnectionNames.has(resolved.name)
3122
3241
  ),
@@ -3189,6 +3308,20 @@ export class SessionEngine {
3189
3308
  }
3190
3309
  continue;
3191
3310
  }
3311
+ const authored = this.authoredConnection(resolved.name);
3312
+ if (
3313
+ sessionId !== undefined &&
3314
+ authored !== undefined &&
3315
+ isCursorAccountTransport(authored.transport)
3316
+ ) {
3317
+ const bound = new URL(url);
3318
+ bound.searchParams.set("agentkitSessionId", sessionId);
3319
+ servers[resolved.name] = {
3320
+ url: bound.toString(),
3321
+ headers: resolved.headers,
3322
+ };
3323
+ continue;
3324
+ }
3192
3325
  servers[resolved.name] = {
3193
3326
  url,
3194
3327
  headers: resolved.headers,
@@ -3198,7 +3331,7 @@ export class SessionEngine {
3198
3331
  runtime === "cloud" &&
3199
3332
  sessionId !== undefined &&
3200
3333
  this.cloudServerToolsConnection !== undefined &&
3201
- this.project.agent.tools.some((tool) => tool.execution === "server")
3334
+ this.project.agent.tools.some(tool => tool.execution === "server")
3202
3335
  ) {
3203
3336
  if (servers[SERVER_TOOLS_MCP_SERVER_NAME] !== undefined) {
3204
3337
  throw new Error(
@@ -3226,7 +3359,7 @@ export class SessionEngine {
3226
3359
  */
3227
3360
  private hasAttachedAuthedConnections(): boolean {
3228
3361
  return this.project.agent.connections.some(
3229
- (connection) =>
3362
+ connection =>
3230
3363
  connection.auth !== undefined && connection.advertiseTools !== true
3231
3364
  );
3232
3365
  }
@@ -3242,7 +3375,7 @@ export class SessionEngine {
3242
3375
  record: SessionRecord
3243
3376
  ): Promise<ReadonlyMap<string, Record<string, string>> | undefined> {
3244
3377
  const authed = this.project.agent.connections.filter(
3245
- (connection) =>
3378
+ connection =>
3246
3379
  connection.auth !== undefined && connection.advertiseTools !== true
3247
3380
  );
3248
3381
  if (authed.length === 0) {
@@ -3269,11 +3402,11 @@ export class SessionEngine {
3269
3402
 
3270
3403
  private async buildCustomTools(
3271
3404
  record: SessionRecord,
3272
- agent: ResolvedAgent,
3273
3405
  turnId: string,
3274
3406
  emit: (payload: SessionEventPayload) => void,
3275
3407
  extraTools: DiscoveredTool[] = []
3276
3408
  ): Promise<Record<string, SDKCustomTool>> {
3409
+ const agent = this.project.agent;
3277
3410
  const tools: Record<string, SDKCustomTool> = {};
3278
3411
  const register = (tool: ResolvedAgent["tools"][number]): void => {
3279
3412
  tools[tool.name] = {
@@ -3358,7 +3491,7 @@ export class SessionEngine {
3358
3491
  );
3359
3492
  }
3360
3493
  const tool = this.project.agent.tools.find(
3361
- (candidate) =>
3494
+ candidate =>
3362
3495
  candidate.name === toolName && candidate.execution === "server"
3363
3496
  );
3364
3497
  if (tool === undefined) {
@@ -3605,11 +3738,11 @@ export class SessionEngine {
3605
3738
  args.sessionId,
3606
3739
  pendingRecord
3607
3740
  );
3608
- await this.updateRecord(args.sessionId, (current) => ({
3741
+ await this.updateRecord(args.sessionId, current => ({
3609
3742
  ...current,
3610
3743
  pendingApprovals: [
3611
3744
  ...(current.pendingApprovals ?? []).filter(
3612
- (item) => item.callId !== args.callId
3745
+ item => item.callId !== args.callId
3613
3746
  ),
3614
3747
  pendingRecord,
3615
3748
  ],
@@ -3626,10 +3759,10 @@ export class SessionEngine {
3626
3759
  `[session] tool ${args.toolName} awaiting approval (${args.callId})`
3627
3760
  );
3628
3761
  const { decision, by } = await resolutionPromise;
3629
- await this.updateRecord(args.sessionId, (current) => ({
3762
+ await this.updateRecord(args.sessionId, current => ({
3630
3763
  ...current,
3631
3764
  pendingApprovals: (current.pendingApprovals ?? []).filter(
3632
- (item) => item.callId !== args.callId
3765
+ item => item.callId !== args.callId
3633
3766
  ),
3634
3767
  }));
3635
3768
  args.emit({
@@ -3656,7 +3789,7 @@ export class SessionEngine {
3656
3789
  ) {
3657
3790
  return;
3658
3791
  }
3659
- await this.updateRecord(sessionId, (record) => ({
3792
+ await this.updateRecord(sessionId, record => ({
3660
3793
  ...record,
3661
3794
  pendingApprovals: [],
3662
3795
  }));
@@ -3699,8 +3832,8 @@ export class SessionEngine {
3699
3832
  throw new SessionAuthError(sessionId);
3700
3833
  }
3701
3834
  const pending =
3702
- (record.pendingApprovals ?? []).find((item) => item.callId === callId) ??
3703
- this.approvals.list(sessionId).find((item) => item.callId === callId);
3835
+ (record.pendingApprovals ?? []).find(item => item.callId === callId) ??
3836
+ this.approvals.list(sessionId).find(item => item.callId === callId);
3704
3837
  if (pending === undefined) {
3705
3838
  throw new ApprovalNotFoundError(sessionId, callId);
3706
3839
  }
@@ -3716,10 +3849,10 @@ export class SessionEngine {
3716
3849
  sessionId: string,
3717
3850
  callId: string
3718
3851
  ): Promise<void> {
3719
- await this.updateRecord(sessionId, (current) => ({
3852
+ await this.updateRecord(sessionId, current => ({
3720
3853
  ...current,
3721
3854
  pendingApprovals: (current.pendingApprovals ?? []).filter(
3722
- (item) => item.callId !== callId
3855
+ item => item.callId !== callId
3723
3856
  ),
3724
3857
  }));
3725
3858
  }
@@ -3727,7 +3860,7 @@ export class SessionEngine {
3727
3860
  private wrapMcp(inner: McpHost): HostMcpRegistry {
3728
3861
  return {
3729
3862
  names: () => inner.names(),
3730
- listTools: (name) => this.withMcpAuth(name, () => inner.listTools(name)),
3863
+ listTools: name => this.withMcpAuth(name, () => inner.listTools(name)),
3731
3864
  callTool: (name, tool, args) =>
3732
3865
  this.withMcpAuth(name, () => inner.callTool(name, tool, args)),
3733
3866
  };
@@ -3735,11 +3868,11 @@ export class SessionEngine {
3735
3868
 
3736
3869
  private advertiseMcp(): AdvertiseHostMcp {
3737
3870
  return {
3738
- listTools: (name) =>
3871
+ listTools: name =>
3739
3872
  this.withMcpListAuth(name, () => this.mcpHost.listTools(name)),
3740
3873
  callTool: (name, tool, args) =>
3741
3874
  this.withMcpAuth(name, () => this.mcpHost.callTool(name, tool, args)),
3742
- oneOff: (connection) => {
3875
+ oneOff: connection => {
3743
3876
  const inner = this.mcpHost.oneOff(connection);
3744
3877
  return {
3745
3878
  listTools: () =>
@@ -3892,11 +4025,11 @@ export class SessionEngine {
3892
4025
  requestedAt,
3893
4026
  };
3894
4027
  const resolutionPromise = this.auths.wait(args.sessionId, pendingRecord);
3895
- await this.updateRecord(args.sessionId, (current) => ({
4028
+ await this.updateRecord(args.sessionId, current => ({
3896
4029
  ...current,
3897
4030
  pendingAuths: [
3898
4031
  ...(current.pendingAuths ?? []).filter(
3899
- (item) => item.callId !== args.callId
4032
+ item => item.callId !== args.callId
3900
4033
  ),
3901
4034
  pendingRecord,
3902
4035
  ],
@@ -3914,10 +4047,10 @@ export class SessionEngine {
3914
4047
  `[session] tool ${args.toolName} awaiting MCP auth ${args.connection} (${args.callId})`
3915
4048
  );
3916
4049
  const { decision, by } = await resolutionPromise;
3917
- await this.updateRecord(args.sessionId, (current) => ({
4050
+ await this.updateRecord(args.sessionId, current => ({
3918
4051
  ...current,
3919
4052
  pendingAuths: (current.pendingAuths ?? []).filter(
3920
- (item) => item.callId !== args.callId
4053
+ item => item.callId !== args.callId
3921
4054
  ),
3922
4055
  }));
3923
4056
  args.emit({
@@ -3946,7 +4079,7 @@ export class SessionEngine {
3946
4079
  ) {
3947
4080
  return;
3948
4081
  }
3949
- await this.updateRecord(sessionId, (record) => ({
4082
+ await this.updateRecord(sessionId, record => ({
3950
4083
  ...record,
3951
4084
  pendingAuths: [],
3952
4085
  }));
@@ -3980,8 +4113,8 @@ export class SessionEngine {
3980
4113
  throw new SessionAuthError(sessionId);
3981
4114
  }
3982
4115
  const pending =
3983
- (record.pendingAuths ?? []).find((item) => item.callId === callId) ??
3984
- this.auths.list(sessionId).find((item) => item.callId === callId);
4116
+ (record.pendingAuths ?? []).find(item => item.callId === callId) ??
4117
+ this.auths.list(sessionId).find(item => item.callId === callId);
3985
4118
  if (pending === undefined) {
3986
4119
  throw new AuthNotFoundError(sessionId, callId);
3987
4120
  }
@@ -4000,10 +4133,10 @@ export class SessionEngine {
4000
4133
  sessionId: string,
4001
4134
  callId: string
4002
4135
  ): Promise<void> {
4003
- await this.updateRecord(sessionId, (current) => ({
4136
+ await this.updateRecord(sessionId, current => ({
4004
4137
  ...current,
4005
4138
  pendingAuths: (current.pendingAuths ?? []).filter(
4006
- (item) => item.callId !== callId
4139
+ item => item.callId !== callId
4007
4140
  ),
4008
4141
  }));
4009
4142
  }
@@ -4211,17 +4344,17 @@ export class SessionEngine {
4211
4344
  }
4212
4345
  > {
4213
4346
  const authored = this.project.agent.tools.find(
4214
- (tool) => tool.name === toolName
4347
+ tool => tool.name === toolName
4215
4348
  );
4216
4349
  if (authored !== undefined) {
4217
4350
  return { tool: authored };
4218
4351
  }
4219
4352
  const catalog = await this.listCatalogTools(options);
4220
- const tool = catalog.tools.find((entry) => entry.name === toolName);
4353
+ const tool = catalog.tools.find(entry => entry.name === toolName);
4221
4354
  if (tool === undefined) {
4222
4355
  return {
4223
4356
  tool: undefined,
4224
- availableTools: catalog.tools.map((entry) => entry.name),
4357
+ availableTools: catalog.tools.map(entry => entry.name),
4225
4358
  connectionErrors: catalog.connectionErrors,
4226
4359
  };
4227
4360
  }
@@ -4263,10 +4396,10 @@ export class SessionEngine {
4263
4396
  if (native !== undefined) {
4264
4397
  return native;
4265
4398
  }
4266
- let tool = this.project.agent.tools.find((t) => t.name === toolName);
4399
+ let tool = this.project.agent.tools.find(t => t.name === toolName);
4267
4400
  if (
4268
4401
  tool === undefined &&
4269
- this.project.agent.connections.some((c) => c.advertiseTools === true)
4402
+ this.project.agent.connections.some(c => c.advertiseTools === true)
4270
4403
  ) {
4271
4404
  // Advertised passthroughs are ordinary server tools in the session's
4272
4405
  // namespace; resolve the live listing so direct calls address them by
@@ -4277,14 +4410,14 @@ export class SessionEngine {
4277
4410
  session,
4278
4411
  hostMcp: this.advertiseMcp(),
4279
4412
  });
4280
- tool = advertised.find((t) => t.name === toolName);
4413
+ tool = advertised.find(t => t.name === toolName);
4281
4414
  }
4282
4415
  if (tool === undefined) {
4283
4416
  throw new UnknownToolError(
4284
4417
  toolName,
4285
4418
  this.project.agent.tools
4286
- .filter((t) => t.execution === "server")
4287
- .map((t) => t.name)
4419
+ .filter(t => t.execution === "server")
4420
+ .map(t => t.name)
4288
4421
  );
4289
4422
  }
4290
4423
  const execute = tool.definition.execute;
@@ -4655,7 +4788,7 @@ export class SessionEngine {
4655
4788
  ): Promise<HostMcpToolInfo | undefined> {
4656
4789
  try {
4657
4790
  const listed = await this.host.mcp.listTools(connectionName);
4658
- return listed.find((tool) => tool.name === toolName);
4791
+ return listed.find(tool => tool.name === toolName);
4659
4792
  } catch {
4660
4793
  return undefined;
4661
4794
  }
@@ -4687,7 +4820,7 @@ export class SessionEngine {
4687
4820
  const chain = this.dispatchChains.get(sessionId) ?? Promise.resolve();
4688
4821
  const next = chain
4689
4822
  .then(() => this.dispatchEvent(sessionId, event, context))
4690
- .catch((error) => {
4823
+ .catch(error => {
4691
4824
  this.logger(
4692
4825
  `[agent-sdk] event dispatch failed for ${sessionId}: ${describeError(error)}`
4693
4826
  );
@@ -4754,11 +4887,11 @@ export class SessionEngine {
4754
4887
  }
4755
4888
  if (context === undefined || channelStateBefore === undefined) {
4756
4889
  // Handlers mutate live channel state in place; save the current record.
4757
- await this.updateRecord(sessionId, (current) => ({ ...current }));
4890
+ await this.updateRecord(sessionId, current => ({ ...current }));
4758
4891
  } else {
4759
4892
  const updatedState = channelCtx.state as JsonValue;
4760
4893
  context.channelState = updatedState;
4761
- await this.updateRecord(sessionId, (current) => ({
4894
+ await this.updateRecord(sessionId, current => ({
4762
4895
  ...current,
4763
4896
  channelState: mergeChannelStateMutation({
4764
4897
  current: current.channelState,
@@ -4796,14 +4929,6 @@ export class SessionEngine {
4796
4929
  }
4797
4930
  }
4798
4931
 
4799
- if (this.abCollector.enabled) {
4800
- await this.abCollector.onEvent(
4801
- event,
4802
- sessionCtx.session,
4803
- this.project.name
4804
- );
4805
- }
4806
-
4807
4932
  this.otel?.onEvent(event, sessionCtx.session);
4808
4933
  }
4809
4934
 
@@ -4850,8 +4975,10 @@ export class SessionEngine {
4850
4975
  async waitForCompletion(sessionId: string): Promise<TurnOutcome> {
4851
4976
  // Drain admission first so pendingTurns → activeTurns is visible before we
4852
4977
  // decide the session is idle (reminders use this for queueBehindTurn).
4853
- // The active lifecycle promise also awaits coalesce drain + the drained
4854
- // follow-up's admission, so Slack coalesced waiters see the resume turn.
4978
+ // Wait for coalesce drain and any successor turn so hosted execute does
4979
+ // not park mid-follow-up, but report the root turn's outcome: a drained
4980
+ // successor failure must not un-ACK an already-finished owner.
4981
+ let root: TurnOutcome | undefined;
4855
4982
  for (;;) {
4856
4983
  const chain = this.admissionChains.get(sessionId);
4857
4984
  if (chain !== undefined) {
@@ -4859,14 +4986,15 @@ export class SessionEngine {
4859
4986
  }
4860
4987
  const active = this.activeTurns.get(sessionId);
4861
4988
  if (active !== undefined) {
4862
- await active;
4989
+ const outcome = await active;
4990
+ root ??= outcome;
4863
4991
  continue;
4864
4992
  }
4865
4993
  const dispatch = this.dispatchChains.get(sessionId);
4866
4994
  if (dispatch !== undefined) {
4867
4995
  await dispatch.catch(() => {});
4868
4996
  }
4869
- return this.lastOutcomes.get(sessionId) ?? { status: "finished" };
4997
+ return root ?? this.lastOutcomes.get(sessionId) ?? { status: "finished" };
4870
4998
  }
4871
4999
  }
4872
5000
 
@@ -4905,7 +5033,7 @@ export class SessionEngine {
4905
5033
  }
4906
5034
  const owned = await this.ownedSessionIds(caller);
4907
5035
  return records.filter(
4908
- (record) => record.sessionId !== undefined && owned.has(record.sessionId)
5036
+ record => record.sessionId !== undefined && owned.has(record.sessionId)
4909
5037
  );
4910
5038
  }
4911
5039
 
@@ -4942,8 +5070,8 @@ export class SessionEngine {
4942
5070
  const sessions = await this.sessions.list();
4943
5071
  return new Set(
4944
5072
  sessions
4945
- .filter((record) => samePrincipal(record.auth, caller))
4946
- .map((record) => record.sessionId)
5073
+ .filter(record => samePrincipal(record.auth, caller))
5074
+ .map(record => record.sessionId)
4947
5075
  );
4948
5076
  }
4949
5077
 
@@ -5087,8 +5215,8 @@ export class SessionEngine {
5087
5215
  includeAll: boolean
5088
5216
  ): SessionSummary[] {
5089
5217
  return records
5090
- .filter((record) => includeAll || samePrincipal(record.auth, caller))
5091
- .map((record) => {
5218
+ .filter(record => includeAll || samePrincipal(record.auth, caller))
5219
+ .map(record => {
5092
5220
  const links = sessionExternalLinks(record);
5093
5221
  return {
5094
5222
  sessionId: record.sessionId,
@@ -5123,61 +5251,6 @@ export class SessionEngine {
5123
5251
  });
5124
5252
  }
5125
5253
 
5126
- /**
5127
- * Fold durable session streams into per-session A/B assignments and
5128
- * aggregate arm metrics (`GET /v1/abs`). Collector-independent: always
5129
- * reads `events.ndjson`.
5130
- */
5131
- async abSnapshot(
5132
- caller: AuthContext | null,
5133
- options?: { includeAll?: boolean }
5134
- ): Promise<ABSnapshot> {
5135
- const sessions = await this.listSessions(caller, options);
5136
- const abConfig = this.project.abConfig;
5137
- const maxPlaygroundSessions = resolveABMaxPlaygroundSessions(
5138
- abConfig?.maxPlaygroundSessions
5139
- );
5140
- const foldedSessions = sessions.slice(0, maxPlaygroundSessions);
5141
- // Backfill for a replacement host with nothing local to fold (e.g.
5142
- // lazy-only restore before any session resumed): serve the persisted
5143
- // aggregate instead of an empty surface. Gated on the host having no
5144
- // sessions AT ALL — the persisted snapshot spans every principal, so a
5145
- // caller who merely owns no sessions must not see it. Loaded once per
5146
- // process (playground polls this route ~every 4s); skip the persist
5147
- // side effect below — re-saving a restored snapshot would echo stale
5148
- // data back into the store.
5149
- if (
5150
- foldedSessions.length === 0 &&
5151
- this.storage !== undefined &&
5152
- (await this.sessions.list()).length === 0
5153
- ) {
5154
- this.restoredAbSnapshot ??= this.storage.getLatestAbSnapshot();
5155
- const restoredSnapshot = await this.restoredAbSnapshot;
5156
- if (restoredSnapshot !== undefined) {
5157
- return restoredSnapshot;
5158
- }
5159
- }
5160
- const abTable = this.project.storage?.abs;
5161
- const snapshot = await buildABSnapshot({
5162
- experiments: this.project.abs,
5163
- agentName: this.project.name,
5164
- sessions: foldedSessions,
5165
- loadRecord: (sessionId) => this.sessions.get(sessionId),
5166
- loadEvents: (sessionId) => this.listEvents(sessionId, 0),
5167
- sessionInfo: (record) => this.sessionInfo(record),
5168
- logger: this.logger,
5169
- config: {
5170
- maxPlaygroundSessions,
5171
- durableSamples: abTable !== undefined,
5172
- durableSnapshots: abTable?.putSnapshot !== undefined,
5173
- },
5174
- });
5175
- // Side effect on the read path: playground polls GET /v1/abs ~every 4s;
5176
- // the coordinator throttles the actual table write.
5177
- this.storage?.abSnapshot(snapshot);
5178
- return snapshot;
5179
- }
5180
-
5181
5254
  async eventStream(
5182
5255
  sessionId: string,
5183
5256
  startIndex = 0
@@ -5202,7 +5275,7 @@ export class SessionEngine {
5202
5275
  if (existing === undefined) {
5203
5276
  throw new Error(`Unknown session: ${sessionId}`);
5204
5277
  }
5205
- const record = await this.updateRecord(sessionId, (current) => ({
5278
+ const record = await this.updateRecord(sessionId, current => ({
5206
5279
  ...current,
5207
5280
  turnCount: current.turnCount + 1,
5208
5281
  }));
@@ -5337,7 +5410,7 @@ export class SessionEngine {
5337
5410
  return pending;
5338
5411
  }
5339
5412
  const work = this.runCloudTurnCostBackfill(sessionId)
5340
- .catch((error) => {
5413
+ .catch(error => {
5341
5414
  this.logger(
5342
5415
  `[agent-sdk] cloud cost backfill failed for ${sessionId}: ${describeError(error)}`
5343
5416
  );
@@ -5352,10 +5425,10 @@ export class SessionEngine {
5352
5425
  private async runCloudTurnCostBackfill(sessionId: string): Promise<void> {
5353
5426
  const log = await this.logs.get(sessionId);
5354
5427
  const events = await log.snapshot(0);
5355
- if (!events.some((event) => isUnpricedCompletedTurn(event))) {
5428
+ if (!events.some(event => isUnpricedCompletedTurn(event))) {
5356
5429
  if (
5357
5430
  !this.isTurnRunning(sessionId) &&
5358
- events.some((event) => event.type === "turn.completed")
5431
+ events.some(event => event.type === "turn.completed")
5359
5432
  ) {
5360
5433
  this.cloudCostBackfillDone.add(sessionId);
5361
5434
  }
@@ -5386,7 +5459,7 @@ export class SessionEngine {
5386
5459
  log.replace(i, next);
5387
5460
  }
5388
5461
  if (
5389
- !(await log.snapshot(0)).some((event) => isUnpricedCompletedTurn(event))
5462
+ !(await log.snapshot(0)).some(event => isUnpricedCompletedTurn(event))
5390
5463
  ) {
5391
5464
  this.cloudCostBackfillDone.add(sessionId);
5392
5465
  }
@@ -5397,7 +5470,7 @@ export class SessionEngine {
5397
5470
  token: string | null
5398
5471
  ): Promise<void> {
5399
5472
  const previous = await this.sessions.get(sessionId);
5400
- await this.updateRecord(sessionId, (current) => ({
5473
+ await this.updateRecord(sessionId, current => ({
5401
5474
  ...current,
5402
5475
  continuationKey: token,
5403
5476
  }));
@@ -5437,7 +5510,6 @@ export class SessionEngine {
5437
5510
  asOf: record.asOf,
5438
5511
  auth: record.auth,
5439
5512
  continuationKey: record.continuationKey,
5440
- ...(record.abs === undefined ? {} : { abs: record.abs }),
5441
5513
  ...(record.title === undefined ? {} : { title: record.title }),
5442
5514
  ...(record.sdkAgentId === undefined
5443
5515
  ? {}
@@ -5539,9 +5611,9 @@ export class SessionEngine {
5539
5611
  * serve start, before channels accept traffic: any persisted session
5540
5612
  * missing from the local `--state-root` is materialized there — events
5541
5613
  * as `events.ndjson`, record as `session.json` — after which every
5542
- * existing read path (continuation lookup, event replay/streams, A/B
5543
- * fold hydration) works unchanged. Local state always wins over the
5544
- * sink, so restarts on the same host are no-ops.
5614
+ * existing read path (continuation lookup, event replay/streams) works
5615
+ * unchanged. Local state always wins over the sink, so restarts on the
5616
+ * same host are no-ops.
5545
5617
  *
5546
5618
  * Failures are logged and skipped; a broken store (including rows that
5547
5619
  * violate the SessionRecord shape) never blocks serve start.
@@ -5575,7 +5647,7 @@ export class SessionEngine {
5575
5647
  // the lazy continuation-lookup path.
5576
5648
  const cutoff = Date.now() - policy.maxAgeMs;
5577
5649
  const candidates = loaded
5578
- .map((record) => ({
5650
+ .map(record => ({
5579
5651
  record,
5580
5652
  // Numeric timestamp for both the age filter and the sort; a
5581
5653
  // non-string updatedAt (e.g. a raw DB Date from an untyped sink)
@@ -5607,7 +5679,7 @@ export class SessionEngine {
5607
5679
  ) {
5608
5680
  const chunk = candidates.slice(i, i + RESTORE_FETCH_CONCURRENCY);
5609
5681
  const fetched = await Promise.all(
5610
- chunk.map(async (record) => {
5682
+ chunk.map(async record => {
5611
5683
  try {
5612
5684
  // Local state always wins over the sink.
5613
5685
  if ((await this.sessions.get(record.sessionId)) !== undefined) {
@@ -5864,7 +5936,7 @@ function eventsNdjson(events: SessionEvent[]): string | undefined {
5864
5936
  if (events.length === 0) {
5865
5937
  return undefined;
5866
5938
  }
5867
- return `${events.map((event) => JSON.stringify(event)).join("\n")}\n`;
5939
+ return `${events.map(event => JSON.stringify(event)).join("\n")}\n`;
5868
5940
  }
5869
5941
 
5870
5942
  function subagentPrompt(subagent: ResolvedAgent): string {
@@ -5880,7 +5952,7 @@ function subagentPrompt(subagent: ResolvedAgent): string {
5880
5952
  * executor that turn will run on.
5881
5953
  */
5882
5954
  function buildRunnerSubagents(agent: ResolvedAgent): RunnerSubagent[] {
5883
- return agent.subagents.map((subagent) => ({
5955
+ return agent.subagents.map(subagent => ({
5884
5956
  name: subagent.name,
5885
5957
  description: subagent.description ?? subagent.name,
5886
5958
  prompt: subagentPrompt(subagent),
@@ -5904,7 +5976,7 @@ async function defaultGetCloudUsage(
5904
5976
  return {
5905
5977
  usage: mapSdkTokenUsage(billed.usage),
5906
5978
  cost: billed.cost,
5907
- runs: billed.runs.map((run) => ({
5979
+ runs: billed.runs.map(run => ({
5908
5980
  runId: run.runId,
5909
5981
  usage: mapSdkTokenUsage(run.usage),
5910
5982
  cost: run.cost,
@@ -5956,7 +6028,7 @@ function approvalResolverLabel(auth: AuthContext | null): string | undefined {
5956
6028
 
5957
6029
  /** Let the HTTP NDJSON writer flush before the next SDK update. */
5958
6030
  function yieldEventLoop(): Promise<void> {
5959
- return new Promise((resolve) => {
6031
+ return new Promise(resolve => {
5960
6032
  setImmediate(resolve);
5961
6033
  });
5962
6034
  }