@cursor/bdk 0.2.1 → 0.2.3

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 (336) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +1 -6
  3. package/dist/artifacts.d.ts +5 -2
  4. package/dist/artifacts.d.ts.map +1 -1
  5. package/dist/artifacts.js +5 -2
  6. package/dist/bin/agent-serve.js +23 -7
  7. package/dist/channels/github/auth.d.ts.map +1 -1
  8. package/dist/channels/github/auth.js +36 -5
  9. package/dist/channels/slack/manifest.d.ts.map +1 -1
  10. package/dist/channels/slack/manifest.js +3 -2
  11. package/dist/channels/slack/types.d.ts +6 -1
  12. package/dist/channels/slack/types.d.ts.map +1 -1
  13. package/dist/connections.d.ts +1 -1
  14. package/dist/connections.js +1 -1
  15. package/dist/docs/404.html +2 -2
  16. package/dist/docs/assets/{app.JVQvbRO-.js → app.BOIHhrKi.js} +4 -4
  17. package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +1 -0
  18. package/dist/docs/assets/chunks/{VPLocalSearchBox.BkhY63uW.js → VPLocalSearchBox.D49zVZqM.js} +1 -1
  19. package/dist/docs/assets/chunks/{arc.Cc1unYd3.js → arc.hmjb-sc4.js} +1 -1
  20. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CAY_TPVz.js → architectureDiagram-Q4EWVU46.CxEI1KqM.js} +1 -1
  21. package/dist/docs/assets/chunks/{baseUniq.my2VD3Xm.js → baseUniq.DHHvBWoV.js} +1 -1
  22. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.CQXAOmqd.js → blockDiagram-DXYQGD6D.DnXW-3bu.js} +1 -1
  23. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.D0AsQFSX.js → c4Diagram-AHTNJAMY.e-47O2jM.js} +1 -1
  24. package/dist/docs/assets/chunks/channel.BbOGaJQP.js +1 -0
  25. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.DZjhgNls.js → chunk-4BX2VUAB.3ry4pYXB.js} +1 -1
  26. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.qdcp_qbo.js → chunk-4TB4RGXK.DGIZFRx6.js} +1 -1
  27. package/dist/docs/assets/chunks/{chunk-55IACEB6.BHXoZhJ-.js → chunk-55IACEB6.DKBnqg9U.js} +1 -1
  28. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.Cds_Vwj3.js → chunk-EDXVE4YY.BIU8Ue5k.js} +1 -1
  29. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CSl0HknT.js → chunk-FMBD7UC4.DP-TFhjI.js} +1 -1
  30. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.DJMvAt5N.js → chunk-OYMX7WX6.Ux0OYj5v.js} +1 -1
  31. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BYQzBK9D.js → chunk-QZHKN3VN.BzHMwYox.js} +1 -1
  32. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.BAvw7N4o.js → chunk-YZCP3GAM.D4OGAsSP.js} +1 -1
  33. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +1 -0
  34. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +1 -0
  35. package/dist/docs/assets/chunks/clone.Co4MBflG.js +1 -0
  36. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Buf3seya.js → cose-bilkent-S5V4N54A.Jq_7BUNx.js} +1 -1
  37. package/dist/docs/assets/chunks/{dagre-KV5264BT.DMGGa3uA.js → dagre-KV5264BT.Di-skR2x.js} +1 -1
  38. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DDjnwRmY.js → diagram-5BDNPKRD.DeREHIdH.js} +1 -1
  39. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.RwyrIr8Q.js → diagram-G4DWMVQ6.C7Kcqxro.js} +1 -1
  40. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DRvQV16Z.js → diagram-MMDJMWI5.BK3eohyo.js} +1 -1
  41. package/dist/docs/assets/chunks/{diagram-TYMM5635.Dw8W9BTk.js → diagram-TYMM5635.C6TyymXT.js} +1 -1
  42. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DQT1Hnwf.js → erDiagram-SMLLAGMA.DYGG-gGx.js} +1 -1
  43. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.6_Aky-ut.js → flowDiagram-DWJPFMVM.C9nBcSV4.js} +1 -1
  44. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DHIwqnqN.js → ganttDiagram-T4ZO3ILL.wAg_ymsp.js} +1 -1
  45. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CGd_eJbn.js → gitGraphDiagram-UUTBAWPF.B87j9Oeg.js} +1 -1
  46. package/dist/docs/assets/chunks/{graph.ChMEylkh.js → graph.CuFMj31w.js} +1 -1
  47. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.Cd4gMyAz.js → infoDiagram-42DDH7IO.P_mLGumP.js} +1 -1
  48. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.D1uw7MXq.js → ishikawaDiagram-UXIWVN3A.DyuL_MsT.js} +1 -1
  49. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.AWLXtelc.js → journeyDiagram-VCZTEJTY.CtP09IoJ.js} +1 -1
  50. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CagPhAn5.js → kanban-definition-6JOO6SKY.BoeSYPZo.js} +1 -1
  51. package/dist/docs/assets/chunks/{layout.ClTBBkE_.js → layout.B0lMMtNo.js} +1 -1
  52. package/dist/docs/assets/chunks/{linear.SwS2rOLA.js → linear.HxRBiAFX.js} +1 -1
  53. package/dist/docs/assets/chunks/{min.By_x-Btb.js → min.BGlFFHwS.js} +1 -1
  54. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.By_RAMaP.js → mindmap-definition-QFDTVHPH.JyLBD9M8.js} +1 -1
  55. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DfAl9sy4.js → pieDiagram-DEJITSTG.DnSmNZF8.js} +1 -1
  56. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CNuqFRBj.js → quadrantDiagram-34T5L4WZ.CUCnbfCa.js} +1 -1
  57. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DJ5CmTCl.js → requirementDiagram-MS252O5E.py0IVUn5.js} +1 -1
  58. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.D-T_AKJj.js → sankeyDiagram-XADWPNL6.Bkc-HWYp.js} +1 -1
  59. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.BRn9WcrR.js → sequenceDiagram-FGHM5R23.Dqn8Mlv2.js} +1 -1
  60. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.F12urmm7.js → stateDiagram-FHFEXIEX.JikkoQUU.js} +1 -1
  61. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +1 -0
  62. package/dist/docs/assets/chunks/{theme.zK3OJa_C.js → theme.b6HQ6zG_.js} +2 -2
  63. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.B7GiQBeC.js → timeline-definition-GMOUNBTQ.BvpSXiBj.js} +1 -1
  64. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.D0niwuY_.js → vennDiagram-DHZGUBPP.CU7MVnZx.js} +1 -1
  65. package/dist/docs/assets/chunks/{wardley-RL74JXVD.1zhHNRsx.js → wardley-RL74JXVD.BKwC4ctG.js} +1 -1
  66. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.DKaqpT7K.js → wardleyDiagram-NUSXRM2D.BfaF6Uhe.js} +1 -1
  67. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.e8BPicch.js → xychartDiagram-5P7HB3ND.Bg5dcpj4.js} +1 -1
  68. package/dist/docs/assets/{deployment.md.nGo1yIsa.js → deployment.md.BJ8i7Q6p.js} +5 -8
  69. package/dist/docs/assets/{deployment.md.nGo1yIsa.lean.js → deployment.md.BJ8i7Q6p.lean.js} +1 -1
  70. package/dist/docs/assets/{guides_github.md.C2_DSWlE.js → guides_github.md.Bq9kQU9B.js} +9 -3
  71. package/dist/docs/assets/{guides_github.md.C2_DSWlE.lean.js → guides_github.md.Bq9kQU9B.lean.js} +1 -1
  72. package/dist/docs/assets/{guides_slack.md.ZbHQETOT.js → guides_slack.md.diqqXTTm.js} +2 -2
  73. package/dist/docs/assets/{guides_slack.md.ZbHQETOT.lean.js → guides_slack.md.diqqXTTm.lean.js} +1 -1
  74. package/dist/docs/assets/{quickstart.md.wG4shE1f.js → quickstart.md.CHpHPBUN.js} +5 -3
  75. package/dist/docs/assets/{quickstart.md.wG4shE1f.lean.js → quickstart.md.CHpHPBUN.lean.js} +1 -1
  76. package/dist/docs/assets/{reference_artifacts.md.IFFC5Zln.js → reference_artifacts.md.CQfKq8F2.js} +1 -1
  77. package/dist/docs/assets/reference_cli.md.DgeLTO18.js +91 -0
  78. package/dist/docs/assets/reference_cli.md.DgeLTO18.lean.js +1 -0
  79. package/dist/docs/assets/{reference_connections.md._XpKiOaF.js → reference_connections.md.COq--gAm.js} +7 -3
  80. package/dist/docs/assets/{reference_connections.md._XpKiOaF.lean.js → reference_connections.md.COq--gAm.lean.js} +1 -1
  81. package/dist/docs/assets/{reference_evals.md.DqNyHMA6.js → reference_evals.md.CJm3uCUm.js} +4 -4
  82. package/dist/docs/assets/{reference_evals.md.DqNyHMA6.lean.js → reference_evals.md.CJm3uCUm.lean.js} +1 -1
  83. package/dist/docs/assets/{reference_hooks.md.Dg3dEugd.js → reference_hooks.md.DbthhtIR.js} +1 -1
  84. package/dist/docs/assets/{reference_sessions.md.BtpTjZmh.js → reference_sessions.md.DeRUItHD.js} +1 -1
  85. package/dist/docs/assets/troubleshooting.md.Cw5PKa3t.js +1 -0
  86. package/dist/docs/assets/{troubleshooting.md.BzZSu1Gz.lean.js → troubleshooting.md.Cw5PKa3t.lean.js} +1 -1
  87. package/dist/docs/building-with-agents.html +35 -35
  88. package/dist/docs/deployment.html +40 -43
  89. package/dist/docs/deployment.md +45 -15
  90. package/dist/docs/evals.html +35 -35
  91. package/dist/docs/guides/agent-to-agent.html +35 -35
  92. package/dist/docs/guides/bitbucket.html +35 -35
  93. package/dist/docs/guides/cloud-agents.html +35 -35
  94. package/dist/docs/guides/convert-automation.html +35 -35
  95. package/dist/docs/guides/github.html +43 -37
  96. package/dist/docs/guides/github.md +34 -0
  97. package/dist/docs/guides/gitlab.html +35 -35
  98. package/dist/docs/guides/grokbot-agents.html +35 -35
  99. package/dist/docs/guides/hooks.html +35 -35
  100. package/dist/docs/guides/improve.html +35 -35
  101. package/dist/docs/guides/jev.html +35 -35
  102. package/dist/docs/guides/mcp-oauth.html +35 -35
  103. package/dist/docs/guides/opentelemetry.html +35 -35
  104. package/dist/docs/guides/slack.html +37 -37
  105. package/dist/docs/guides/slack.md +5 -0
  106. package/dist/docs/guides/webhooks.html +35 -35
  107. package/dist/docs/hashmap.json +1 -1
  108. package/dist/docs/hillclimbing.html +35 -35
  109. package/dist/docs/index.html +35 -35
  110. package/dist/docs/llms-full.txt +205 -97
  111. package/dist/docs/quickstart.html +40 -38
  112. package/dist/docs/quickstart.md +7 -1
  113. package/dist/docs/reference/agent-config.html +35 -35
  114. package/dist/docs/reference/artifacts.html +37 -37
  115. package/dist/docs/reference/artifacts.md +1 -1
  116. package/dist/docs/reference/channels.html +35 -35
  117. package/dist/docs/reference/cli.html +55 -61
  118. package/dist/docs/reference/cli.md +65 -63
  119. package/dist/docs/reference/connections.html +42 -38
  120. package/dist/docs/reference/connections.md +28 -2
  121. package/dist/docs/reference/evals.html +39 -39
  122. package/dist/docs/reference/evals.md +6 -7
  123. package/dist/docs/reference/extensions.html +35 -35
  124. package/dist/docs/reference/hooks.html +37 -37
  125. package/dist/docs/reference/hooks.md +3 -2
  126. package/dist/docs/reference/http-api.html +35 -35
  127. package/dist/docs/reference/instructions.html +35 -35
  128. package/dist/docs/reference/playground.html +35 -35
  129. package/dist/docs/reference/project-layout.html +35 -35
  130. package/dist/docs/reference/prompt.html +35 -35
  131. package/dist/docs/reference/schedules.html +35 -35
  132. package/dist/docs/reference/sessions.html +36 -36
  133. package/dist/docs/reference/sessions.md +4 -3
  134. package/dist/docs/reference/skills.html +35 -35
  135. package/dist/docs/reference/subagents.html +35 -35
  136. package/dist/docs/reference/tools.html +35 -35
  137. package/dist/docs/templates/agentic-owners.html +35 -35
  138. package/dist/docs/templates/security-reviewer.html +35 -35
  139. package/dist/docs/templates/thermo-quality-review.html +35 -35
  140. package/dist/docs/templates/thermo-review.html +35 -35
  141. package/dist/docs/templates/triage.html +35 -35
  142. package/dist/docs/troubleshooting.html +36 -36
  143. package/dist/docs/troubleshooting.md +7 -3
  144. package/dist/extensions/cursor-cloud-agents/extension.d.ts +16 -4
  145. package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
  146. package/dist/extensions/cursor-cloud-agents/extension.js +7 -3
  147. package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts +3 -0
  148. package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts.map +1 -0
  149. package/dist/extensions/cursor-cloud-agents/lib/channels.js +7 -0
  150. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +4 -2
  151. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -1
  152. package/dist/extensions/cursor-cloud-agents/lib/repos.js +21 -12
  153. package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts.map +1 -1
  154. package/dist/extensions/cursor-cloud-agents/tools/cancel.js +2 -0
  155. package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
  156. package/dist/extensions/cursor-cloud-agents/tools/launch.js +3 -1
  157. package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts.map +1 -1
  158. package/dist/extensions/cursor-cloud-agents/tools/reply.js +2 -0
  159. package/dist/extensions/cursor-grokbot-agents/extension.d.ts +77 -0
  160. package/dist/extensions/cursor-grokbot-agents/extension.d.ts.map +1 -0
  161. package/dist/extensions/cursor-grokbot-agents/extension.js +63 -0
  162. package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts +11 -0
  163. package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts.map +1 -0
  164. package/dist/extensions/cursor-grokbot-agents/lib/agents.js +31 -0
  165. package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts +56 -0
  166. package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts.map +1 -0
  167. package/dist/extensions/cursor-grokbot-agents/lib/backend.js +158 -0
  168. package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts +28 -0
  169. package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts.map +1 -0
  170. package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +59 -0
  171. package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts +53 -0
  172. package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts.map +1 -0
  173. package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +206 -0
  174. package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts +4 -0
  175. package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts.map +1 -0
  176. package/dist/extensions/cursor-grokbot-agents/lib/inputs.js +15 -0
  177. package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts +12 -0
  178. package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts.map +1 -0
  179. package/dist/extensions/cursor-grokbot-agents/lib/lock.js +25 -0
  180. package/dist/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
  181. package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts +4 -0
  182. package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts.map +1 -0
  183. package/dist/extensions/cursor-grokbot-agents/tools/ask.js +37 -0
  184. package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts +4 -0
  185. package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts.map +1 -0
  186. package/dist/extensions/cursor-grokbot-agents/tools/check.js +32 -0
  187. package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts +4 -0
  188. package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts.map +1 -0
  189. package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +24 -0
  190. package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts +4 -0
  191. package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts.map +1 -0
  192. package/dist/extensions/cursor-grokbot-agents/tools/list.js +34 -0
  193. package/dist/files-backends/cursor-hosted.js +4 -4
  194. package/dist/internal/artifacts-store.d.ts +12 -2
  195. package/dist/internal/artifacts-store.d.ts.map +1 -1
  196. package/dist/internal/artifacts-store.js +8 -4
  197. package/dist/internal/cli-ax.d.ts +1 -0
  198. package/dist/internal/cli-ax.d.ts.map +1 -1
  199. package/dist/internal/cli-ax.js +43 -10
  200. package/dist/internal/cli-deploy.d.ts +5 -1
  201. package/dist/internal/cli-deploy.d.ts.map +1 -1
  202. package/dist/internal/cli-deploy.js +22 -4
  203. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  204. package/dist/internal/cli-mcp-oauth.js +2 -1
  205. package/dist/internal/cli-skills.d.ts +1 -1
  206. package/dist/internal/cli-skills.d.ts.map +1 -1
  207. package/dist/internal/cli-skills.js +5 -5
  208. package/dist/internal/connection-env.d.ts +31 -0
  209. package/dist/internal/connection-env.d.ts.map +1 -0
  210. package/dist/internal/connection-env.js +84 -0
  211. package/dist/internal/cursor/backend-client.js +5 -0
  212. package/dist/internal/deploy-client.d.ts +30 -6
  213. package/dist/internal/deploy-client.d.ts.map +1 -1
  214. package/dist/internal/deploy-client.js +45 -9
  215. package/dist/internal/discovery/connections.d.ts.map +1 -1
  216. package/dist/internal/discovery/connections.js +11 -0
  217. package/dist/internal/event-mapper.d.ts +46 -4
  218. package/dist/internal/event-mapper.d.ts.map +1 -1
  219. package/dist/internal/event-mapper.js +316 -25
  220. package/dist/internal/hosted-delivery-protocol.d.ts +36 -11
  221. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  222. package/dist/internal/hosted-delivery-protocol.js +31 -8
  223. package/dist/internal/hosted-delivery.d.ts +2 -2
  224. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  225. package/dist/internal/hosted-delivery.js +229 -49
  226. package/dist/internal/hosting.d.ts +2 -2
  227. package/dist/internal/hosting.d.ts.map +1 -1
  228. package/dist/internal/hosting.js +9 -3
  229. package/dist/internal/install-cursor-skills.d.ts +20 -24
  230. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  231. package/dist/internal/install-cursor-skills.js +50 -48
  232. package/dist/internal/legacy-command-guard.d.ts +2 -0
  233. package/dist/internal/legacy-command-guard.d.ts.map +1 -1
  234. package/dist/internal/legacy-command-guard.js +10 -1
  235. package/dist/internal/mcp-host.d.ts +6 -0
  236. package/dist/internal/mcp-host.d.ts.map +1 -1
  237. package/dist/internal/mcp-host.js +35 -16
  238. package/dist/internal/sdk-runner.d.ts +2 -0
  239. package/dist/internal/sdk-runner.d.ts.map +1 -1
  240. package/dist/internal/sdk-runner.js +10 -0
  241. package/dist/internal/server.d.ts.map +1 -1
  242. package/dist/internal/server.js +11 -1
  243. package/dist/internal/session-engine.d.ts +1 -1
  244. package/dist/internal/session-engine.d.ts.map +1 -1
  245. package/dist/internal/session-engine.js +33 -8
  246. package/dist/playground/assets/index-6BbTPnaT.css +1 -0
  247. package/dist/playground/assets/{index-FFdUqTt_.js → index-CI7FAmOP.js} +43 -43
  248. package/dist/playground/index.html +2 -2
  249. package/dist/types.d.ts +50 -4
  250. package/dist/types.d.ts.map +1 -1
  251. package/docs/deployment.md +45 -15
  252. package/docs/guides/github.md +34 -0
  253. package/docs/guides/slack.md +5 -0
  254. package/docs/quickstart.md +7 -1
  255. package/docs/reference/artifacts.md +1 -1
  256. package/docs/reference/cli.md +65 -63
  257. package/docs/reference/connections.md +28 -2
  258. package/docs/reference/evals.md +6 -7
  259. package/docs/reference/hooks.md +3 -2
  260. package/docs/reference/sessions.md +4 -3
  261. package/docs/troubleshooting.md +7 -3
  262. package/package.json +2 -4
  263. package/scripts/install-cursor-skills.mjs +1 -1
  264. package/skills/create-agent/SKILL.md +1 -1
  265. package/skills/debug/SKILL.md +1 -1
  266. package/skills/deploy/SKILL.md +1 -1
  267. package/skills/evals/SKILL.md +1 -1
  268. package/skills/framework-map/SKILL.md +1 -1
  269. package/skills/github/SKILL.md +1 -1
  270. package/skills/hillclimb/SKILL.md +1 -1
  271. package/skills/mcp-auth/SKILL.md +1 -1
  272. package/skills/otel/SKILL.md +1 -1
  273. package/skills/setup-slack/SKILL.md +1 -1
  274. package/src/artifacts.ts +5 -2
  275. package/src/bin/agent-serve.ts +27 -6
  276. package/src/channels/github/auth.ts +44 -5
  277. package/src/channels/slack/manifest.ts +2 -1
  278. package/src/channels/slack/types.ts +6 -1
  279. package/src/connections.ts +1 -1
  280. package/src/extensions/cursor-cloud-agents/extension.ts +23 -6
  281. package/src/extensions/cursor-cloud-agents/lib/channels.ts +11 -0
  282. package/src/extensions/cursor-cloud-agents/lib/repos.ts +19 -7
  283. package/src/extensions/cursor-cloud-agents/tools/cancel.ts +2 -0
  284. package/src/extensions/cursor-cloud-agents/tools/launch.ts +3 -1
  285. package/src/extensions/cursor-cloud-agents/tools/reply.ts +2 -0
  286. package/src/extensions/cursor-grokbot-agents/extension.ts +132 -0
  287. package/src/extensions/cursor-grokbot-agents/lib/agents.ts +42 -0
  288. package/src/extensions/cursor-grokbot-agents/lib/backend.ts +208 -0
  289. package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +74 -0
  290. package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +260 -0
  291. package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +21 -0
  292. package/src/extensions/cursor-grokbot-agents/lib/lock.ts +26 -0
  293. package/src/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
  294. package/src/extensions/cursor-grokbot-agents/tools/ask.ts +32 -0
  295. package/src/extensions/cursor-grokbot-agents/tools/check.ts +25 -0
  296. package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +17 -0
  297. package/src/extensions/cursor-grokbot-agents/tools/list.ts +26 -0
  298. package/src/files-backends/cursor-hosted.ts +4 -4
  299. package/src/internal/artifacts-store.ts +14 -3
  300. package/src/internal/cli-ax.ts +52 -7
  301. package/src/internal/cli-deploy.ts +39 -6
  302. package/src/internal/cli-mcp-oauth.ts +2 -1
  303. package/src/internal/cli-skills.ts +4 -5
  304. package/src/internal/connection-env.ts +106 -0
  305. package/src/internal/cursor/backend-client.ts +6 -0
  306. package/src/internal/deploy-client.ts +79 -9
  307. package/src/internal/discovery/connections.ts +11 -0
  308. package/src/internal/event-mapper.ts +367 -36
  309. package/src/internal/hosted-delivery-protocol.ts +57 -20
  310. package/src/internal/hosted-delivery.ts +487 -229
  311. package/src/internal/hosting.ts +10 -3
  312. package/src/internal/install-cursor-skills.ts +56 -53
  313. package/src/internal/legacy-command-guard.ts +13 -1
  314. package/src/internal/mcp-host.ts +45 -17
  315. package/src/internal/sdk-runner.ts +11 -0
  316. package/src/internal/server.ts +13 -1
  317. package/src/internal/session-engine.ts +33 -13
  318. package/src/types.ts +56 -5
  319. package/templates/agents-md/bot/lib/collect.ts +1 -4
  320. package/templates/code-wiki/bot/channels/github.ts +2 -2
  321. package/templates/demo/bot/channels/github.ts +5 -1
  322. package/templates/pr-autofixer/bot/lib/start-drive.ts +4 -4
  323. package/templates/triage/bot/lib/types.ts +6 -6
  324. package/dist/docs/assets/chunks/@localSearchIndexroot.Caw9W1pM.js +0 -1
  325. package/dist/docs/assets/chunks/channel.Sapo9HJZ.js +0 -1
  326. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.NPiy3Hz7.js +0 -1
  327. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.NPiy3Hz7.js +0 -1
  328. package/dist/docs/assets/chunks/clone.zl2qolPE.js +0 -1
  329. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2._auCa3fR.js +0 -1
  330. package/dist/docs/assets/reference_cli.md.BK2QUH67.js +0 -97
  331. package/dist/docs/assets/reference_cli.md.BK2QUH67.lean.js +0 -1
  332. package/dist/docs/assets/troubleshooting.md.BzZSu1Gz.js +0 -1
  333. package/dist/playground/assets/index-BMV_IcEE.css +0 -1
  334. /package/dist/docs/assets/{reference_artifacts.md.IFFC5Zln.lean.js → reference_artifacts.md.CQfKq8F2.lean.js} +0 -0
  335. /package/dist/docs/assets/{reference_hooks.md.Dg3dEugd.lean.js → reference_hooks.md.DbthhtIR.lean.js} +0 -0
  336. /package/dist/docs/assets/{reference_sessions.md.BtpTjZmh.lean.js → reference_sessions.md.DeRUItHD.lean.js} +0 -0
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { InteractionUpdate as SdkInteractionUpdate, ToolCall } from "@cursor/sdk";
8
- import type { SessionEventPayload, TurnUsage } from "../types.js";
8
+ import type { ActionCall, ActionResult, SessionEventPayload, TurnUsage } from "../types.js";
9
9
 
10
10
  const CUSTOM_TOOLS_PROVIDER = "custom-user-tools";
11
11
  /** Authored server tools on cloud turns; keep in sync with `SERVER_TOOLS_MCP_SERVER_NAME`. */
@@ -39,7 +39,8 @@ type NestedTaskUpdate =
39
39
  modelCallId: string;
40
40
  }
41
41
  | { type: "step-started"; stepId: number }
42
- | { type: "step-completed"; stepId: number; stepDurationMs: number };
42
+ | { type: "step-completed"; stepId: number; stepDurationMs: number }
43
+ | { type: "tool-requests-listed"; callCount: number };
43
44
 
44
45
  type ToolCallDeltaUpdate = {
45
46
  type: "tool-call-delta";
@@ -48,8 +49,13 @@ type ToolCallDeltaUpdate = {
48
49
  taskUpdate: NestedTaskUpdate;
49
50
  };
50
51
 
51
- /** SDK updates plus nested task deltas once the SDK exposes them. */
52
- type InteractionUpdate = SdkInteractionUpdate | ToolCallDeltaUpdate;
52
+ type ToolRequestsListedUpdate = {
53
+ type: "tool-requests-listed";
54
+ callCount: number;
55
+ };
56
+
57
+ /** SDK updates plus list-closed / nested task deltas ahead of `@cursor/sdk`. */
58
+ type InteractionUpdate = SdkInteractionUpdate | ToolCallDeltaUpdate | ToolRequestsListedUpdate;
53
59
 
54
60
  function asToolCallDelta(update: InteractionUpdate): ToolCallDeltaUpdate | undefined {
55
61
  if ((update as { type: string }).type !== "tool-call-delta") {
@@ -58,6 +64,12 @@ function asToolCallDelta(update: InteractionUpdate): ToolCallDeltaUpdate | undef
58
64
  return update as ToolCallDeltaUpdate;
59
65
  }
60
66
 
67
+ function modelCallIdOf(update: { modelCallId?: unknown }): string | undefined {
68
+ return typeof update.modelCallId === "string" && update.modelCallId !== ""
69
+ ? update.modelCallId
70
+ : undefined;
71
+ }
72
+
61
73
  export interface ToolCallDescription {
62
74
  toolName: string;
63
75
  args?: unknown;
@@ -74,6 +86,17 @@ interface NestedAccumulators {
74
86
  reasoning: string;
75
87
  }
76
88
 
89
+ type ToolWave = {
90
+ key: string;
91
+ modelCallId?: string;
92
+ parentCallId?: string;
93
+ calls: ActionCall[];
94
+ results: ActionResult[];
95
+ expectedCalls?: number;
96
+ requestedEmitted: boolean;
97
+ completedEmitted: boolean;
98
+ };
99
+
77
100
  export class TurnEventMapper {
78
101
  private textAccumulator = "";
79
102
  private reasoningAccumulator = "";
@@ -82,6 +105,17 @@ export class TurnEventMapper {
82
105
  private summaryTitle: string | undefined;
83
106
  /** Per-parent-call accumulators for nested subagent streams. */
84
107
  private readonly nested = new Map<string, NestedAccumulators>();
108
+ /** One wave per model step (or per call when the step id is missing). */
109
+ private readonly waves = new Map<string, ToolWave>();
110
+ /**
111
+ * Keys of waves that already emitted `actions.completed`, plus each
112
+ * finished call's singleton key. A late duplicate cannot reopen the
113
+ * batch or emit a second pair for the same callId. A new late callId
114
+ * still gets its own singleton.
115
+ */
116
+ private readonly sealedWaveKeys = new Set<string>();
117
+ /** Listed-call count from `tool-requests-listed`, keyed by parentCallId. */
118
+ private readonly listedCounts = new Map<string, number>();
85
119
 
86
120
  /**
87
121
  * @param isStubbed Reports whether a finished tool call was answered by the
@@ -173,17 +207,25 @@ export class TurnEventMapper {
173
207
  }
174
208
  case "tool-call-started": {
175
209
  this.flushAssistantText("tool_call");
176
- this.emitToolStarted(update.callId, update.toolCall);
210
+ this.noteToolStarted(update.callId, update.toolCall, {
211
+ modelCallId: modelCallIdOf(update),
212
+ });
177
213
  return;
178
214
  }
179
215
  case "tool-call-completed": {
180
- this.emitToolCompleted(update.callId, update.toolCall);
216
+ this.noteToolCompleted(update.callId, update.toolCall, {
217
+ modelCallId: modelCallIdOf(update),
218
+ });
181
219
  return;
182
220
  }
183
221
  case "step-started": {
184
222
  this.emit({ type: "step.started", data: { stepId: update.stepId } });
185
223
  return;
186
224
  }
225
+ case "tool-requests-listed": {
226
+ this.noteRequestsListed(undefined, update.callCount);
227
+ return;
228
+ }
187
229
  case "step-completed": {
188
230
  this.emit({
189
231
  type: "step.completed",
@@ -223,6 +265,8 @@ export class TurnEventMapper {
223
265
 
224
266
  /** Close out the turn: finalize any open assistant text block. */
225
267
  finish(): void {
268
+ this.sealOpenRequests();
269
+ this.flushOpenResults();
226
270
  this.flushAssistantText("stop");
227
271
  for (const parentCallId of this.nested.keys()) {
228
272
  this.flushNestedAssistantText(parentCallId, "stop");
@@ -273,15 +317,26 @@ export class TurnEventMapper {
273
317
  }
274
318
  case "tool-call-started": {
275
319
  this.flushNestedAssistantText(parentCallId, "tool_call");
276
- this.emitToolStarted(update.callId, update.toolCall, parentCallId);
320
+ this.noteToolStarted(update.callId, update.toolCall, {
321
+ parentCallId,
322
+ modelCallId: modelCallIdOf(update),
323
+ });
277
324
  return;
278
325
  }
279
326
  case "tool-call-completed": {
280
- this.emitToolCompleted(update.callId, update.toolCall, parentCallId);
327
+ this.noteToolCompleted(update.callId, update.toolCall, {
328
+ parentCallId,
329
+ modelCallId: modelCallIdOf(update),
330
+ });
281
331
  return;
282
332
  }
283
333
  case "partial-tool-call":
334
+ return;
284
335
  case "step-started":
336
+ return;
337
+ case "tool-requests-listed":
338
+ this.noteRequestsListed(parentCallId, update.callCount);
339
+ return;
285
340
  case "step-completed":
286
341
  return;
287
342
  default: {
@@ -290,22 +345,36 @@ export class TurnEventMapper {
290
345
  }
291
346
  }
292
347
 
293
- private emitToolStarted(callId: string, toolCall: ToolCall, parentCallId?: string): void {
348
+ private noteToolStarted(
349
+ callId: string,
350
+ toolCall: ToolCall,
351
+ ids?: { parentCallId?: string; modelCallId?: string },
352
+ ): void {
353
+ const parentCallId = ids?.parentCallId;
354
+ const modelCallId = ids?.modelCallId;
294
355
  const description = describeToolCall(toolCall);
295
- this.emit({
296
- type: "actions.requested",
297
- data: {
298
- calls: [
299
- {
300
- callId,
301
- toolName: description.toolName,
302
- args: description.args,
303
- parentCallId,
304
- },
305
- ],
356
+ const call: ActionCall = {
357
+ callId,
358
+ toolName: description.toolName,
359
+ args: description.args,
360
+ parentCallId,
361
+ modelCallId,
362
+ };
363
+ if (modelCallId !== undefined) {
364
+ this.sealOpenRequests({
306
365
  parentCallId,
307
- },
308
- });
366
+ exceptModelCallId: modelCallId,
367
+ });
368
+ }
369
+ const wave = this.waveForStart({ parentCallId, modelCallId, callId });
370
+ if (wave === undefined) {
371
+ return;
372
+ }
373
+ if (wave.calls.every(existing => existing.callId !== callId)) {
374
+ wave.calls.push(call);
375
+ }
376
+ this.adoptSingletonResults(wave, parentCallId, callId);
377
+ this.maybeSealListedWave(wave);
309
378
  // Subagent bookends only fire for the top-level task tool, not nested
310
379
  // tools inside a subagent (nested subagents aren't supported).
311
380
  if (description.subagent !== undefined && parentCallId === undefined) {
@@ -318,22 +387,44 @@ export class TurnEventMapper {
318
387
  },
319
388
  });
320
389
  }
390
+ if (wave.modelCallId === undefined) {
391
+ this.sealWaveRequests(wave);
392
+ }
321
393
  }
322
394
 
323
- private emitToolCompleted(callId: string, toolCall: ToolCall, parentCallId?: string): void {
395
+ private noteToolCompleted(
396
+ callId: string,
397
+ toolCall: ToolCall,
398
+ ids?: { parentCallId?: string; modelCallId?: string },
399
+ ): void {
400
+ const parentCallId = ids?.parentCallId;
401
+ const modelCallId = ids?.modelCallId;
324
402
  const description = describeToolCall(toolCall);
325
403
  const result = describeToolResult(toolCall);
326
- this.emit({
327
- type: "action.result",
328
- data: {
329
- callId,
330
- toolName: description.toolName,
331
- output: result.output,
332
- isError: result.isError,
333
- ...(this.isStubbed(callId) ? { stubbed: true as const } : {}),
334
- parentCallId,
335
- },
336
- });
404
+ const actionResult: ActionResult = {
405
+ callId,
406
+ toolName: description.toolName,
407
+ output: result.output,
408
+ isError: result.isError,
409
+ stubbed: this.isStubbed(callId) ? true : undefined,
410
+ parentCallId,
411
+ modelCallId,
412
+ };
413
+ const wave = this.waveForComplete({ parentCallId, modelCallId, callId });
414
+ if (wave === undefined) {
415
+ return;
416
+ }
417
+ const isNew = wave.results.every(existing => existing.callId !== callId);
418
+ if (isNew) {
419
+ wave.results.push(actionResult);
420
+ }
421
+ if (wave.requestedEmitted && isNew) {
422
+ this.emit({
423
+ type: "action.result",
424
+ data: actionResult,
425
+ });
426
+ this.maybeEmitActionsCompleted(wave);
427
+ }
337
428
  if (description.subagent !== undefined && parentCallId === undefined) {
338
429
  this.flushNestedAssistantText(callId, "stop");
339
430
  this.nested.delete(callId);
@@ -344,6 +435,242 @@ export class TurnEventMapper {
344
435
  }
345
436
  }
346
437
 
438
+ private callBelongsToWave(wave: ToolWave, callId: string): boolean {
439
+ return (
440
+ wave.calls.some(existing => existing.callId === callId) ||
441
+ wave.results.some(existing => existing.callId === callId)
442
+ );
443
+ }
444
+
445
+ private singletonWave(parentCallId: string | undefined, callId: string): ToolWave | undefined {
446
+ const key = waveKey({ parentCallId, callId });
447
+ if (this.sealedWaveKeys.has(key) && !this.waves.has(key)) {
448
+ return undefined;
449
+ }
450
+ return this.ensureWave(key, { parentCallId });
451
+ }
452
+
453
+ /**
454
+ * Starts join the open model-step wave until `actions.requested` seals.
455
+ * A later start for that same step is its own singleton pair so completed
456
+ * cannot list tools the matching requested envelope never had.
457
+ */
458
+ private waveForStart(ids: {
459
+ parentCallId?: string;
460
+ modelCallId?: string;
461
+ callId: string;
462
+ }): ToolWave | undefined {
463
+ const groupedKey = waveKey(ids);
464
+ const grouped = this.waves.get(groupedKey);
465
+ if (grouped !== undefined && !grouped.requestedEmitted) {
466
+ return grouped;
467
+ }
468
+ if (grouped !== undefined && this.callBelongsToWave(grouped, ids.callId)) {
469
+ return grouped;
470
+ }
471
+ if (grouped !== undefined && grouped.requestedEmitted) {
472
+ return this.singletonWave(ids.parentCallId, ids.callId);
473
+ }
474
+ if (this.sealedWaveKeys.has(groupedKey)) {
475
+ return this.singletonWave(ids.parentCallId, ids.callId);
476
+ }
477
+ return this.ensureWave(groupedKey, {
478
+ modelCallId: ids.modelCallId,
479
+ parentCallId: ids.parentCallId,
480
+ });
481
+ }
482
+
483
+ /**
484
+ * Completes join a model-step wave only when that call already started
485
+ * there. A start-less complete on an open sibling batch would flush with
486
+ * `actions.requested` and then block `actions.completed` forever.
487
+ */
488
+ private waveForComplete(ids: {
489
+ parentCallId?: string;
490
+ modelCallId?: string;
491
+ callId: string;
492
+ }): ToolWave | undefined {
493
+ const groupedKey = waveKey(ids);
494
+ const grouped = this.waves.get(groupedKey);
495
+ if (grouped !== undefined && this.callBelongsToWave(grouped, ids.callId)) {
496
+ return grouped;
497
+ }
498
+ if (grouped !== undefined) {
499
+ return this.singletonWave(ids.parentCallId, ids.callId);
500
+ }
501
+ if (this.sealedWaveKeys.has(groupedKey)) {
502
+ return this.waves.get(waveKey({ parentCallId: ids.parentCallId, callId: ids.callId }));
503
+ }
504
+ return this.ensureWave(groupedKey, {
505
+ modelCallId: ids.modelCallId,
506
+ parentCallId: ids.parentCallId,
507
+ });
508
+ }
509
+
510
+ private adoptSingletonResults(
511
+ wave: ToolWave,
512
+ parentCallId: string | undefined,
513
+ callId: string,
514
+ ): void {
515
+ const singletonKey = waveKey({ parentCallId, callId });
516
+ if (singletonKey === wave.key) {
517
+ return;
518
+ }
519
+ const singleton = this.waves.get(singletonKey);
520
+ if (singleton === undefined) {
521
+ return;
522
+ }
523
+ for (const result of singleton.results) {
524
+ if (wave.results.every(existing => existing.callId !== result.callId)) {
525
+ wave.results.push(result);
526
+ }
527
+ }
528
+ this.waves.delete(singletonKey);
529
+ }
530
+
531
+ private ensureWave(key: string, ids: { modelCallId?: string; parentCallId?: string }): ToolWave {
532
+ let wave = this.waves.get(key);
533
+ if (wave === undefined) {
534
+ const expectedCalls = this.listedCounts.get(ids.parentCallId ?? "");
535
+ wave = {
536
+ key,
537
+ modelCallId: ids.modelCallId,
538
+ parentCallId: ids.parentCallId,
539
+ expectedCalls,
540
+ calls: [],
541
+ results: [],
542
+ requestedEmitted: false,
543
+ completedEmitted: false,
544
+ };
545
+ this.waves.set(key, wave);
546
+ }
547
+ return wave;
548
+ }
549
+
550
+ private noteRequestsListed(parentCallId: string | undefined, callCount: number): void {
551
+ const listed = Math.max(0, callCount);
552
+ if (listed === 0) {
553
+ this.sealOpenRequests({ parentCallId });
554
+ this.listedCounts.delete(parentCallId ?? "");
555
+ return;
556
+ }
557
+ this.listedCounts.set(parentCallId ?? "", listed);
558
+ for (const wave of this.waves.values()) {
559
+ if (wave.parentCallId !== parentCallId || wave.requestedEmitted) {
560
+ continue;
561
+ }
562
+ wave.expectedCalls = listed;
563
+ this.maybeSealListedWave(wave);
564
+ }
565
+ }
566
+
567
+ private maybeSealListedWave(wave: ToolWave): void {
568
+ const expected = wave.expectedCalls ?? this.listedCounts.get(wave.parentCallId ?? "");
569
+ if (expected !== undefined && wave.calls.length >= expected) {
570
+ this.sealWaveRequests(wave);
571
+ }
572
+ }
573
+
574
+ private sealOpenRequests(ids?: { parentCallId?: string; exceptModelCallId?: string }): void {
575
+ const parentCallId = ids?.parentCallId;
576
+ const exceptModelCallId = ids?.exceptModelCallId;
577
+ for (const wave of this.waves.values()) {
578
+ if (wave.parentCallId !== parentCallId) {
579
+ continue;
580
+ }
581
+ if (exceptModelCallId !== undefined && wave.modelCallId === exceptModelCallId) {
582
+ continue;
583
+ }
584
+ this.sealWaveRequests(wave);
585
+ }
586
+ }
587
+
588
+ private sealWaveRequests(wave: ToolWave): void {
589
+ if (wave.requestedEmitted || wave.calls.length === 0) {
590
+ return;
591
+ }
592
+ wave.requestedEmitted = true;
593
+ this.listedCounts.delete(wave.parentCallId ?? "");
594
+ this.emit({
595
+ type: "actions.requested",
596
+ data: {
597
+ calls: wave.calls,
598
+ parentCallId: wave.parentCallId,
599
+ modelCallId: wave.modelCallId,
600
+ },
601
+ });
602
+ for (const result of wave.results) {
603
+ this.emit({
604
+ type: "action.result",
605
+ data: result,
606
+ });
607
+ }
608
+ this.maybeEmitActionsCompleted(wave);
609
+ }
610
+
611
+ private maybeEmitActionsCompleted(wave: ToolWave): void {
612
+ if (
613
+ wave.completedEmitted ||
614
+ !wave.requestedEmitted ||
615
+ wave.calls.length === 0 ||
616
+ wave.results.length < wave.calls.length
617
+ ) {
618
+ return;
619
+ }
620
+ const callIds = new Set(wave.calls.map(call => call.callId));
621
+ if (!wave.results.every(result => callIds.has(result.callId))) {
622
+ return;
623
+ }
624
+ if (!wave.calls.every(call => wave.results.some(result => result.callId === call.callId))) {
625
+ return;
626
+ }
627
+ this.emitActionsCompleted(wave);
628
+ }
629
+
630
+ private emitActionsCompleted(wave: ToolWave): void {
631
+ wave.completedEmitted = true;
632
+ this.emit({
633
+ type: "actions.completed",
634
+ data: {
635
+ results: wave.results,
636
+ parentCallId: wave.parentCallId,
637
+ modelCallId: wave.modelCallId,
638
+ },
639
+ });
640
+ this.forgetWave(wave);
641
+ }
642
+
643
+ private forgetWave(wave: ToolWave): void {
644
+ this.waves.delete(wave.key);
645
+ this.sealedWaveKeys.add(wave.key);
646
+ for (const callId of new Set([
647
+ ...wave.calls.map(call => call.callId),
648
+ ...wave.results.map(result => result.callId),
649
+ ])) {
650
+ this.sealedWaveKeys.add(waveKey({ parentCallId: wave.parentCallId, callId }));
651
+ }
652
+ wave.calls = [];
653
+ wave.results = [];
654
+ }
655
+
656
+ private flushOpenResults(): void {
657
+ for (const wave of [...this.waves.values()]) {
658
+ if (wave.calls.length === 0 && wave.results.length > 0) {
659
+ wave.calls = wave.results.map(result => ({
660
+ callId: result.callId,
661
+ toolName: result.toolName,
662
+ parentCallId: result.parentCallId,
663
+ modelCallId: result.modelCallId,
664
+ }));
665
+ }
666
+ this.sealWaveRequests(wave);
667
+ this.maybeEmitActionsCompleted(wave);
668
+ if (!wave.completedEmitted) {
669
+ this.forgetWave(wave);
670
+ }
671
+ }
672
+ }
673
+
347
674
  private ensureNested(parentCallId: string): NestedAccumulators {
348
675
  let acc = this.nested.get(parentCallId);
349
676
  if (acc === undefined) {
@@ -415,10 +742,10 @@ export function describeToolCall(toolCall: ToolCall): ToolCallDescription {
415
742
  toolName: "task",
416
743
  args: {
417
744
  description: toolCall.args.description,
418
- ...(subagentName === undefined ? {} : { subagentType: subagentName }),
745
+ subagentType: subagentName,
419
746
  },
420
747
  subagent: {
421
- ...(subagentName === undefined ? {} : { name: subagentName }),
748
+ name: subagentName,
422
749
  description: toolCall.args.description,
423
750
  },
424
751
  };
@@ -462,6 +789,10 @@ export function describeToolResult(toolCall: ToolCall): ToolResultDescription {
462
789
  return { output: result.value, isError: false };
463
790
  }
464
791
 
792
+ function waveKey(ids: { parentCallId?: string; modelCallId?: string; callId: string }): string {
793
+ return `${ids.parentCallId ?? ""}:${ids.modelCallId ?? `call:${ids.callId}`}`;
794
+ }
795
+
465
796
  function addUsage(total: TurnUsage | undefined, usage: TurnUsage): TurnUsage {
466
797
  if (total === undefined) {
467
798
  return { ...usage };
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Private control-plane/engine wire contract. Version 2 is unreleased and
3
+ * intentionally strict: unknown fields and modes fail closed. After release,
4
+ * any shape or semantic change must use a new version and a rolling
5
+ * compatibility window. See `docs/agent-serve/hosted-delivery-protocol.md`.
6
+ */
1
7
  export const HOSTED_DELIVERY_PROTOCOL_VERSION = 2;
2
8
  export const HOSTED_DELIVERY_HEADER = "x-agent-sdk-hosted-delivery";
3
9
  export const HOSTED_ADMISSION_PATH = "/v1/internal/hosted-admission";
@@ -251,7 +257,7 @@ export type HostedAdmissionPlatformHandoff = {
251
257
  };
252
258
  };
253
259
 
254
- export type HostedAdmission = {
260
+ export type HostedAdmissionInput = {
255
261
  v: 2;
256
262
  channelId: string;
257
263
  /**
@@ -270,9 +276,20 @@ export type HostedAdmission = {
270
276
  platformHandoff?: HostedAdmissionPlatformHandoff;
271
277
  };
272
278
 
279
+ export type HostedAdmissionStart = HostedAdmissionInput & { mode: "start" };
280
+
281
+ export type HostedAdmissionStatus = {
282
+ v: 2;
283
+ mode: "status";
284
+ deliveryId: string;
285
+ };
286
+
287
+ export type HostedAdmission = HostedAdmissionStart | HostedAdmissionStatus;
288
+
273
289
  export type HostedAdmissionOutcome =
274
290
  | { ok: true; v: 2; outcome: "skip" | "task" }
275
- | { ok: true; v: 2; outcome: "send"; admissionToken: string };
291
+ | { ok: true; v: 2; outcome: "send"; admissionToken: string }
292
+ | { ok: true; v: 2; outcome: "started" | "running" };
276
293
 
277
294
  /**
278
295
  * Cap on delivery IDs an owner execute may report as consumed (primary +
@@ -281,19 +298,19 @@ export type HostedAdmissionOutcome =
281
298
  */
282
299
  export const HOSTED_MAX_CONSUMED_DELIVERY_IDS = 16;
283
300
 
284
- /** Hosted-execution run mode. Omitted/`execute` is the legacy wait path. */
285
- export type HostedExecutionMode = "execute" | "enqueue";
301
+ /** Hosted-execution is unary: start/status for owners, enqueue for guests. */
302
+ export type HostedExecutionMode = "enqueue" | "start" | "status";
286
303
 
287
304
  export type HostedExecution = {
288
305
  v: 2;
289
306
  admissionToken: string;
290
307
  sessionPublicId: string;
291
308
  /**
292
- * `execute` (default when omitted) runs the owner send and waits for the
293
- * coalesce chain. `enqueue` injects into an accepting owner or returns
294
- * `not_active`.
309
+ * `enqueue` injects into an accepting owner or returns `not_active`.
310
+ * `start` launches the owner turn and returns `started` immediately.
311
+ * `status` returns `running` or replays the terminal response.
295
312
  */
296
- mode?: HostedExecutionMode;
313
+ mode: HostedExecutionMode;
297
314
  };
298
315
 
299
316
  export type HostedExecutionOutcome =
@@ -303,16 +320,17 @@ export type HostedExecutionOutcome =
303
320
  outcome: "send";
304
321
  /**
305
322
  * Primary delivery id then accepted enqueue ids; length 1..16.
306
- * Optional for old-guest compatibility; callers must normalize absent
307
- * lists to `[primaryDeliveryId]`.
308
323
  */
309
- consumedDeliveryIds?: string[];
324
+ consumedDeliveryIds: string[];
310
325
  }
311
326
  | { ok: true; v: 2; outcome: "enqueued" }
312
- | { ok: true; v: 2; outcome: "not_active" };
327
+ | { ok: true; v: 2; outcome: "not_active" }
328
+ | { ok: true; v: 2; outcome: "started" }
329
+ | { ok: true; v: 2; outcome: "running" };
313
330
 
314
331
  const DELIVERY_KEYS = new Set([
315
332
  "v",
333
+ "mode",
316
334
  "channelId",
317
335
  "channelKind",
318
336
  "eventType",
@@ -435,10 +453,18 @@ export function parseHostedAdmission(value: unknown): HostedAdmission | undefine
435
453
  return undefined;
436
454
  }
437
455
  const body = value as Record<string, unknown>;
456
+ if (body.mode === "status") {
457
+ return Object.keys(body).every(key => key === "v" || key === "mode" || key === "deliveryId") &&
458
+ body.v === HOSTED_DELIVERY_PROTOCOL_VERSION &&
459
+ boundedString(body.deliveryId, 256)
460
+ ? (body as HostedAdmissionStatus)
461
+ : undefined;
462
+ }
438
463
  if (
439
464
  Object.keys(body).some(key => !DELIVERY_KEYS.has(key)) ||
440
465
  !Object.hasOwn(body, "payload") ||
441
466
  body.v !== HOSTED_DELIVERY_PROTOCOL_VERSION ||
467
+ body.mode !== "start" ||
442
468
  !boundedString(body.channelId, 128) ||
443
469
  !boundedString(body.channelKind, 128) ||
444
470
  !boundedString(body.eventType, 128) ||
@@ -468,7 +494,7 @@ export function parseHostedExecution(value: unknown): HostedExecution | undefine
468
494
  ) {
469
495
  return undefined;
470
496
  }
471
- if (body.mode !== undefined && body.mode !== "execute" && body.mode !== "enqueue") {
497
+ if (body.mode !== "enqueue" && body.mode !== "start" && body.mode !== "status") {
472
498
  return undefined;
473
499
  }
474
500
  return body as HostedExecution;
@@ -501,7 +527,12 @@ export function parseHostedExecutionOutcome(value: unknown): HostedExecutionOutc
501
527
  ) {
502
528
  return undefined;
503
529
  }
504
- if (body.outcome === "enqueued" || body.outcome === "not_active") {
530
+ if (
531
+ body.outcome === "enqueued" ||
532
+ body.outcome === "not_active" ||
533
+ body.outcome === "started" ||
534
+ body.outcome === "running"
535
+ ) {
505
536
  if (body.consumedDeliveryIds !== undefined) {
506
537
  return undefined;
507
538
  }
@@ -510,10 +541,6 @@ export function parseHostedExecutionOutcome(value: unknown): HostedExecutionOutc
510
541
  if (body.outcome !== "send") {
511
542
  return undefined;
512
543
  }
513
- // Old guests omit consumedDeliveryIds; accept and let callers normalize.
514
- if (body.consumedDeliveryIds === undefined) {
515
- return { ok: true, v: 2, outcome: "send" };
516
- }
517
544
  const consumedDeliveryIds = parseConsumedDeliveryIds(body.consumedDeliveryIds);
518
545
  if (consumedDeliveryIds === undefined) {
519
546
  return undefined;
@@ -530,7 +557,7 @@ export function parseHostedExecutionOutcome(value: unknown): HostedExecutionOutc
530
557
  * True when the admission envelope is the reserved internal reminder fire
531
558
  * path (not an authored channel event).
532
559
  */
533
- export function isHostedReminderAdmission(delivery: HostedAdmission): boolean {
560
+ export function isHostedReminderAdmission(delivery: HostedAdmissionInput): boolean {
534
561
  return (
535
562
  delivery.channelKind === HOSTED_REMINDER_CHANNEL_KIND &&
536
563
  delivery.eventType === HOSTED_REMINDER_EVENT_TYPE
@@ -768,20 +795,30 @@ export function parseHostedReminderFireDescriptorPayload(
768
795
  };
769
796
  }
770
797
 
798
+ const HOSTED_ADMISSION_OUTCOME_KEYS = new Set(["ok", "v", "outcome", "admissionToken"]);
799
+
771
800
  export function parseHostedAdmissionOutcome(value: unknown): HostedAdmissionOutcome | undefined {
772
801
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
773
802
  return undefined;
774
803
  }
775
804
  const body = value as Record<string, unknown>;
776
805
  if (
806
+ Object.keys(body).some(key => !HOSTED_ADMISSION_OUTCOME_KEYS.has(key)) ||
777
807
  body.ok !== true ||
778
808
  body.v !== HOSTED_DELIVERY_PROTOCOL_VERSION ||
779
- (body.outcome !== "skip" && body.outcome !== "send" && body.outcome !== "task")
809
+ (body.outcome !== "skip" &&
810
+ body.outcome !== "send" &&
811
+ body.outcome !== "task" &&
812
+ body.outcome !== "started" &&
813
+ body.outcome !== "running")
780
814
  ) {
781
815
  return undefined;
782
816
  }
783
817
  if (body.outcome === "send" && !boundedString(body.admissionToken, 128)) {
784
818
  return undefined;
785
819
  }
820
+ if (body.outcome !== "send" && Object.hasOwn(body, "admissionToken")) {
821
+ return undefined;
822
+ }
786
823
  return body as HostedAdmissionOutcome;
787
824
  }