@cursor/bdk 0.2.14 → 0.2.16

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 (392) hide show
  1. package/AGENTS.md +51 -52
  2. package/README.md +1 -1
  3. package/dist/bin/agent-sdk.js +0 -0
  4. package/dist/bin/agent-serve.js +41 -3
  5. package/dist/channels/github/index.d.ts +1 -1
  6. package/dist/channels/github/index.d.ts.map +1 -1
  7. package/dist/channels/github/index.js +1 -1
  8. package/dist/channels/slack/attachments.d.ts +2 -0
  9. package/dist/channels/slack/attachments.d.ts.map +1 -1
  10. package/dist/channels/slack/attachments.js +17 -5
  11. package/dist/channels/slack/channel-watch.d.ts +4 -2
  12. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  13. package/dist/channels/slack/channel-watch.js +4 -2
  14. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  15. package/dist/channels/slack/slack-channel.js +4 -2
  16. package/dist/channels/slack/types.d.ts +6 -4
  17. package/dist/channels/slack/types.d.ts.map +1 -1
  18. package/dist/connections.d.ts +29 -0
  19. package/dist/connections.d.ts.map +1 -1
  20. package/dist/connections.js +54 -0
  21. package/dist/docs/404.html +2 -2
  22. package/dist/docs/assets/{app.BN3sgOOo.js → app.BSrZkTHD.js} +4 -4
  23. package/dist/docs/assets/{building-with-agents.md.Df87rAe1.js → building-with-agents.md.Bi9CQ-bR.js} +3 -3
  24. package/dist/docs/assets/{building-with-agents.md.Df87rAe1.lean.js → building-with-agents.md.Bi9CQ-bR.lean.js} +1 -1
  25. package/dist/docs/assets/chunks/@localSearchIndexroot.JUnN1Be1.js +1 -0
  26. package/dist/docs/assets/chunks/{VPLocalSearchBox.CbA00dML.js → VPLocalSearchBox.BxmgcwIX.js} +1 -1
  27. package/dist/docs/assets/chunks/{arc.Byug8CZM.js → arc.CAid9y9R.js} +1 -1
  28. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.D1_qmnQy.js → architectureDiagram-Q4EWVU46.kLxg-1A5.js} +1 -1
  29. package/dist/docs/assets/chunks/{baseUniq.Dj-Nurf-.js → baseUniq.BWvpjFlO.js} +1 -1
  30. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.BZwq3EIg.js → blockDiagram-DXYQGD6D.DyjX8R7M.js} +1 -1
  31. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.dx75urO7.js → c4Diagram-AHTNJAMY.DBdWlnqr.js} +1 -1
  32. package/dist/docs/assets/chunks/channel.CWc3NN9g.js +1 -0
  33. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CIoddsDQ.js → chunk-4BX2VUAB.T5enPS2D.js} +1 -1
  34. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.O3VsVBES.js → chunk-4TB4RGXK.D6zswRAS.js} +1 -1
  35. package/dist/docs/assets/chunks/{chunk-55IACEB6.WNNWh0Pe.js → chunk-55IACEB6.Bh05N-a3.js} +1 -1
  36. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BKVQwEME.js → chunk-EDXVE4YY.DZv_O-d9.js} +1 -1
  37. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.Cv5iBz7A.js → chunk-FMBD7UC4.BY53CZaL.js} +1 -1
  38. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.wCDCToee.js → chunk-OYMX7WX6.CO5lI2PE.js} +1 -1
  39. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.D3IGXhXA.js → chunk-QZHKN3VN.DMfpW0s4.js} +1 -1
  40. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.CAPPh-E7.js → chunk-YZCP3GAM.COPT56Nr.js} +1 -1
  41. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D5a745iS.js +1 -0
  42. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D5a745iS.js +1 -0
  43. package/dist/docs/assets/chunks/clone.CCGVqN_B.js +1 -0
  44. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BQCFH3M5.js → cose-bilkent-S5V4N54A.BJSj7zzd.js} +1 -1
  45. package/dist/docs/assets/chunks/{dagre-KV5264BT.lHmdrh7L.js → dagre-KV5264BT.DDv7IQZT.js} +1 -1
  46. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.EtSPnHgD.js → diagram-5BDNPKRD.BUoE9HFH.js} +1 -1
  47. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DCyUnQT8.js → diagram-G4DWMVQ6.BF3JtrnJ.js} +1 -1
  48. package/dist/docs/assets/chunks/{diagram-MMDJMWI5._E0Qqblb.js → diagram-MMDJMWI5.BvuCWc4e.js} +1 -1
  49. package/dist/docs/assets/chunks/{diagram-TYMM5635.BDj4oyy_.js → diagram-TYMM5635._EqUGqFN.js} +1 -1
  50. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.CrvnO6a3.js → erDiagram-SMLLAGMA.DxNvSdzj.js} +1 -1
  51. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.DIhYc-2F.js → flowDiagram-DWJPFMVM.DVtRP546.js} +1 -1
  52. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.hFqm_vio.js → ganttDiagram-T4ZO3ILL.Bn9vb7xI.js} +1 -1
  53. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.N3GDaVDD.js → gitGraphDiagram-UUTBAWPF.45r6n737.js} +1 -1
  54. package/dist/docs/assets/chunks/{graph.DK28rMBx.js → graph.BOkX3Ws_.js} +1 -1
  55. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.DHmE6W9M.js → infoDiagram-42DDH7IO.DyBCcxOm.js} +1 -1
  56. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.ByUJuOYm.js → ishikawaDiagram-UXIWVN3A.kg0ywDlx.js} +1 -1
  57. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.BIUChFMh.js → journeyDiagram-VCZTEJTY.BUfrLnXA.js} +1 -1
  58. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CNgFXwo-.js → kanban-definition-6JOO6SKY.Bn7X35b2.js} +1 -1
  59. package/dist/docs/assets/chunks/{layout.BDnwE4ET.js → layout.B0QW6d8M.js} +1 -1
  60. package/dist/docs/assets/chunks/{linear.DmrYLXFs.js → linear.C59eCF0D.js} +1 -1
  61. package/dist/docs/assets/chunks/{min.BbYcWakN.js → min.BnDl0p08.js} +1 -1
  62. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.C9x-klkv.js → mindmap-definition-QFDTVHPH.u2HYLooo.js} +1 -1
  63. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.iufpEbi0.js → pieDiagram-DEJITSTG.CbnIrr9l.js} +1 -1
  64. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.DdoXbWL9.js → quadrantDiagram-34T5L4WZ.D2zWIixq.js} +1 -1
  65. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.XL1-_pNk.js → requirementDiagram-MS252O5E.DvOFa3oO.js} +1 -1
  66. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DySXofNs.js → sankeyDiagram-XADWPNL6.BfKCkH3x.js} +1 -1
  67. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.Cp0GZoOU.js → sequenceDiagram-FGHM5R23.CUPKdYN0.js} +1 -1
  68. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.DvK-sXUX.js → stateDiagram-FHFEXIEX.CimDCRiK.js} +1 -1
  69. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.ClNUVSTQ.js +1 -0
  70. package/dist/docs/assets/chunks/{theme.Clup4iIo.js → theme.CKht7z82.js} +2 -2
  71. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.gHI9ZLm6.js → timeline-definition-GMOUNBTQ.BFTd5qKs.js} +1 -1
  72. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.G2N2zXYe.js → vennDiagram-DHZGUBPP.N6t5MmCb.js} +1 -1
  73. package/dist/docs/assets/chunks/wardley-RL74JXVD.D2G6Zyds.js +162 -0
  74. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BgUKEagd.js → wardleyDiagram-NUSXRM2D.BqScALbL.js} +1 -1
  75. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CwH7oege.js → xychartDiagram-5P7HB3ND.Br0WiDkT.js} +1 -1
  76. package/dist/docs/assets/deployment.md.hKKN9I4c.js +31 -0
  77. package/dist/docs/assets/{deployment.md.BYuEcDBv.lean.js → deployment.md.hKKN9I4c.lean.js} +1 -1
  78. package/dist/docs/assets/{evals.md.C851kViu.js → evals.md.CHR34K1Y.js} +3 -7
  79. package/dist/docs/assets/{evals.md.C851kViu.lean.js → evals.md.CHR34K1Y.lean.js} +1 -1
  80. package/dist/docs/assets/guides_cloud-agents.md.CBK7W0-O.js +9 -0
  81. package/dist/docs/assets/guides_cloud-agents.md.CBK7W0-O.lean.js +1 -0
  82. package/dist/docs/assets/guides_grokbot-agents.md.BwAykJ7U.js +15 -0
  83. package/dist/docs/assets/{guides_grokbot-agents.md.tD1smFhU.lean.js → guides_grokbot-agents.md.BwAykJ7U.lean.js} +1 -1
  84. package/dist/docs/assets/{guides_hooks.md.5Ce3NXxZ.js → guides_hooks.md.B_bKG1oA.js} +1 -1
  85. package/dist/docs/assets/{guides_improve.md.CRrYq22s.js → guides_improve.md.CZKVt1cT.js} +2 -3
  86. package/dist/docs/assets/{guides_improve.md.CRrYq22s.lean.js → guides_improve.md.CZKVt1cT.lean.js} +1 -1
  87. package/dist/docs/assets/{guides_mcp-oauth.md.DR3zhC9r.js → guides_mcp-oauth.md.BM_eFC0L.js} +3 -15
  88. package/dist/docs/assets/guides_mcp-oauth.md.BM_eFC0L.lean.js +1 -0
  89. package/dist/docs/assets/{guides_webhooks.md.BBvAm_VF.js → guides_webhooks.md.Cpdc3BDX.js} +13 -12
  90. package/dist/docs/assets/{guides_webhooks.md.BBvAm_VF.lean.js → guides_webhooks.md.Cpdc3BDX.lean.js} +1 -1
  91. package/dist/docs/assets/{index.md.Dxxr7pFa.js → index.md.BIBHIQtU.js} +1 -1
  92. package/dist/docs/assets/{quickstart.md.BK5gjHM2.js → quickstart.md.CduLGBAB.js} +1 -1
  93. package/dist/docs/assets/{reference_agent-config.md.DrtLxWgR.js → reference_agent-config.md.DYA6ge6t.js} +7 -4
  94. package/dist/docs/assets/{reference_agent-config.md.DrtLxWgR.lean.js → reference_agent-config.md.DYA6ge6t.lean.js} +1 -1
  95. package/dist/docs/assets/reference_channels.md.DYg0CLud.js +22 -0
  96. package/dist/docs/assets/{reference_channels.md.LbNIJBwd.lean.js → reference_channels.md.DYg0CLud.lean.js} +1 -1
  97. package/dist/docs/assets/{reference_cli.md.dYCAL2lB.js → reference_cli.md.2d2Y0O-d.js} +16 -13
  98. package/dist/docs/assets/{reference_cli.md.dYCAL2lB.lean.js → reference_cli.md.2d2Y0O-d.lean.js} +1 -1
  99. package/dist/docs/assets/{reference_connections.md.DLrgAd5f.js → reference_connections.md.CxbLpaaP.js} +4 -5
  100. package/dist/docs/assets/{reference_connections.md.DLrgAd5f.lean.js → reference_connections.md.CxbLpaaP.lean.js} +1 -1
  101. package/dist/docs/assets/{reference_evals.md.D5i8PuXJ.js → reference_evals.md.Ccwp4x3o.js} +4 -4
  102. package/dist/docs/assets/{reference_evals.md.D5i8PuXJ.lean.js → reference_evals.md.Ccwp4x3o.lean.js} +1 -1
  103. package/dist/docs/assets/{reference_hooks.md.B-eGa2km.js → reference_hooks.md.DbJC8mcZ.js} +1 -1
  104. package/dist/docs/assets/reference_http-api.md.CrqhTv6S.js +11 -0
  105. package/dist/docs/assets/{reference_http-api.md.DbFNOubV.lean.js → reference_http-api.md.CrqhTv6S.lean.js} +1 -1
  106. package/dist/docs/assets/reference_playground.md.q4MI-0td.js +1 -0
  107. package/dist/docs/assets/reference_playground.md.q4MI-0td.lean.js +1 -0
  108. package/dist/docs/assets/{reference_schedules.md.BuJ8fgMa.js → reference_schedules.md.03Ryy9ca.js} +5 -5
  109. package/dist/docs/assets/{reference_schedules.md.BuJ8fgMa.lean.js → reference_schedules.md.03Ryy9ca.lean.js} +1 -1
  110. package/dist/docs/assets/reference_sessions.md.C_uzIWuy.js +1 -0
  111. package/dist/docs/assets/{reference_skills.md.ClkMoQsV.js → reference_skills.md.C2GWh7g8.js} +4 -4
  112. package/dist/docs/assets/{reference_tools.md.DzIY9JzY.js → reference_tools.md.08XR7lIl.js} +3 -14
  113. package/dist/docs/assets/reference_tools.md.08XR7lIl.lean.js +1 -0
  114. package/dist/docs/assets/{templates_grokbot-agents.md.2sydjFiO.js → templates_grokbot-agents.md.DgpPEs7B.js} +1 -1
  115. package/dist/docs/assets/troubleshooting.md.PCafNCb5.js +1 -0
  116. package/dist/docs/assets/{troubleshooting.md.x-GBa7wN.lean.js → troubleshooting.md.PCafNCb5.lean.js} +1 -1
  117. package/dist/docs/building-with-agents.html +37 -37
  118. package/dist/docs/building-with-agents.md +5 -5
  119. package/dist/docs/deployment.html +43 -41
  120. package/dist/docs/deployment.md +70 -33
  121. package/dist/docs/evals.html +38 -42
  122. package/dist/docs/evals.md +1 -16
  123. package/dist/docs/guides/agent-to-agent.html +35 -35
  124. package/dist/docs/guides/bitbucket.html +35 -35
  125. package/dist/docs/guides/cloud-agents.html +38 -39
  126. package/dist/docs/guides/cloud-agents.md +2 -8
  127. package/dist/docs/guides/convert-automation.html +35 -35
  128. package/dist/docs/guides/github.html +35 -35
  129. package/dist/docs/guides/gitlab.html +35 -35
  130. package/dist/docs/guides/grokbot-agents.html +37 -38
  131. package/dist/docs/guides/grokbot-agents.md +9 -13
  132. package/dist/docs/guides/hooks.html +37 -37
  133. package/dist/docs/guides/hooks.md +0 -1
  134. package/dist/docs/guides/improve.html +37 -38
  135. package/dist/docs/guides/improve.md +4 -6
  136. package/dist/docs/guides/jev.html +35 -35
  137. package/dist/docs/guides/mcp-oauth.html +39 -51
  138. package/dist/docs/guides/mcp-oauth.md +17 -40
  139. package/dist/docs/guides/migrate.html +35 -35
  140. package/dist/docs/guides/opentelemetry.html +35 -35
  141. package/dist/docs/guides/slack.html +35 -35
  142. package/dist/docs/guides/webhooks.html +47 -46
  143. package/dist/docs/guides/webhooks.md +35 -18
  144. package/dist/docs/hashmap.json +1 -1
  145. package/dist/docs/hillclimbing.html +35 -35
  146. package/dist/docs/index.html +36 -36
  147. package/dist/docs/index.md +1 -1
  148. package/dist/docs/llms-full.txt +388 -272
  149. package/dist/docs/llms.txt +4 -4
  150. package/dist/docs/quickstart.html +37 -37
  151. package/dist/docs/quickstart.md +2 -2
  152. package/dist/docs/reference/agent-config.html +41 -38
  153. package/dist/docs/reference/agent-config.md +26 -1
  154. package/dist/docs/reference/artifacts.html +35 -35
  155. package/dist/docs/reference/channels.html +42 -43
  156. package/dist/docs/reference/channels.md +29 -13
  157. package/dist/docs/reference/cli.html +50 -47
  158. package/dist/docs/reference/cli.md +115 -42
  159. package/dist/docs/reference/connections.html +39 -40
  160. package/dist/docs/reference/connections.md +6 -5
  161. package/dist/docs/reference/evals.html +38 -38
  162. package/dist/docs/reference/evals.md +15 -4
  163. package/dist/docs/reference/extensions.html +35 -35
  164. package/dist/docs/reference/hooks.html +37 -37
  165. package/dist/docs/reference/hooks.md +0 -1
  166. package/dist/docs/reference/http-api.html +38 -38
  167. package/dist/docs/reference/http-api.md +7 -17
  168. package/dist/docs/reference/instructions.html +35 -35
  169. package/dist/docs/reference/playground.html +37 -37
  170. package/dist/docs/reference/playground.md +1 -4
  171. package/dist/docs/reference/project-layout.html +35 -35
  172. package/dist/docs/reference/prompt.html +35 -35
  173. package/dist/docs/reference/schedules.html +39 -39
  174. package/dist/docs/reference/schedules.md +26 -3
  175. package/dist/docs/reference/sessions.html +36 -36
  176. package/dist/docs/reference/sessions.md +1 -2
  177. package/dist/docs/reference/skills.html +39 -39
  178. package/dist/docs/reference/skills.md +1 -1
  179. package/dist/docs/reference/subagents.html +35 -35
  180. package/dist/docs/reference/tools.html +39 -50
  181. package/dist/docs/reference/tools.md +2 -28
  182. package/dist/docs/templates/agentic-owners.html +35 -35
  183. package/dist/docs/templates/grokbot-agents.html +37 -37
  184. package/dist/docs/templates/grokbot-agents.md +1 -1
  185. package/dist/docs/templates/security-reviewer.html +35 -35
  186. package/dist/docs/templates/thermo-quality-review.html +35 -35
  187. package/dist/docs/templates/thermo-review.html +35 -35
  188. package/dist/docs/templates/triage.html +35 -35
  189. package/dist/docs/troubleshooting.html +36 -36
  190. package/dist/docs/troubleshooting.md +12 -7
  191. package/dist/extensions/cursor-cloud-agents/extension.d.ts +5 -1
  192. package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
  193. package/dist/extensions/cursor-cloud-agents/extension.js +4 -0
  194. package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts.map +1 -1
  195. package/dist/extensions/cursor-cloud-agents/lib/channels.js +5 -1
  196. package/dist/filesystem.d.ts.map +1 -1
  197. package/dist/filesystem.js +4 -8
  198. package/dist/internal/cli-convert-automation.js +9 -19
  199. package/dist/internal/cli-deploy.d.ts +1 -1
  200. package/dist/internal/cli-deploy.d.ts.map +1 -1
  201. package/dist/internal/cli-deploy.js +18 -3
  202. package/dist/internal/cli-init-grokbot.d.ts +29 -0
  203. package/dist/internal/cli-init-grokbot.d.ts.map +1 -0
  204. package/dist/internal/cli-init-grokbot.js +181 -0
  205. package/dist/internal/cli-slack.js +1 -1
  206. package/dist/internal/comment-safe.d.ts +8 -0
  207. package/dist/internal/comment-safe.d.ts.map +1 -0
  208. package/dist/internal/comment-safe.js +12 -0
  209. package/dist/internal/continuation-identity.js +1 -1
  210. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
  211. package/dist/internal/convert-automation/convert-workflow.js +2 -14
  212. package/dist/internal/convert-grokbot/answers.d.ts +127 -0
  213. package/dist/internal/convert-grokbot/answers.d.ts.map +1 -0
  214. package/dist/internal/convert-grokbot/answers.js +443 -0
  215. package/dist/internal/convert-grokbot/bot.d.ts +50 -0
  216. package/dist/internal/convert-grokbot/bot.d.ts.map +1 -0
  217. package/dist/internal/convert-grokbot/bot.js +72 -0
  218. package/dist/internal/convert-grokbot/checks.d.ts +26 -0
  219. package/dist/internal/convert-grokbot/checks.d.ts.map +1 -0
  220. package/dist/internal/convert-grokbot/checks.js +170 -0
  221. package/dist/internal/convert-grokbot/convert.d.ts +60 -0
  222. package/dist/internal/convert-grokbot/convert.d.ts.map +1 -0
  223. package/dist/internal/convert-grokbot/convert.js +470 -0
  224. package/dist/internal/convert-grokbot/handoff.d.ts +44 -0
  225. package/dist/internal/convert-grokbot/handoff.d.ts.map +1 -0
  226. package/dist/internal/convert-grokbot/handoff.js +160 -0
  227. package/dist/internal/convert-grokbot/recipe.d.ts +61 -0
  228. package/dist/internal/convert-grokbot/recipe.d.ts.map +1 -0
  229. package/dist/internal/convert-grokbot/recipe.js +94 -0
  230. package/dist/internal/convert-grokbot/routine.d.ts +51 -0
  231. package/dist/internal/convert-grokbot/routine.d.ts.map +1 -0
  232. package/dist/internal/convert-grokbot/routine.js +128 -0
  233. package/dist/internal/convert-grokbot/slack.d.ts +28 -0
  234. package/dist/internal/convert-grokbot/slack.d.ts.map +1 -0
  235. package/dist/internal/convert-grokbot/slack.js +50 -0
  236. package/dist/internal/deploy-client.d.ts +0 -2
  237. package/dist/internal/deploy-client.d.ts.map +1 -1
  238. package/dist/internal/deploy-client.js +2 -11
  239. package/dist/internal/discovery/agent-config.d.ts +6 -0
  240. package/dist/internal/discovery/agent-config.d.ts.map +1 -1
  241. package/dist/internal/discovery/agent-config.js +19 -0
  242. package/dist/internal/discovery/agent.d.ts.map +1 -1
  243. package/dist/internal/discovery/agent.js +2 -1
  244. package/dist/internal/discovery/names.d.ts +2 -0
  245. package/dist/internal/discovery/names.d.ts.map +1 -1
  246. package/dist/internal/discovery/names.js +2 -0
  247. package/dist/internal/discovery/project.d.ts.map +1 -1
  248. package/dist/internal/discovery/project.js +1 -3
  249. package/dist/internal/eval-judge-model.d.ts +10 -5
  250. package/dist/internal/eval-judge-model.d.ts.map +1 -1
  251. package/dist/internal/eval-judge-model.js +36 -25
  252. package/dist/internal/filesystem/subagent-inherit.d.ts +39 -0
  253. package/dist/internal/filesystem/subagent-inherit.d.ts.map +1 -0
  254. package/dist/internal/filesystem/subagent-inherit.js +96 -0
  255. package/dist/internal/filesystem/tools.d.ts +6 -0
  256. package/dist/internal/filesystem/tools.d.ts.map +1 -1
  257. package/dist/internal/filesystem/tools.js +38 -1
  258. package/dist/internal/hosted-catch-protocol.d.ts +2 -0
  259. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
  260. package/dist/internal/hosted-catch-protocol.js +2 -0
  261. package/dist/internal/hosted-catch.d.ts +2 -3
  262. package/dist/internal/hosted-catch.d.ts.map +1 -1
  263. package/dist/internal/hosted-catch.js +2 -3
  264. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  265. package/dist/internal/hosted-delivery.js +46 -13
  266. package/dist/internal/hosted-execution-flush.d.ts +6 -3
  267. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  268. package/dist/internal/hosted-execution-flush.js +28 -31
  269. package/dist/internal/hosting.d.ts +1 -1
  270. package/dist/internal/hosting.d.ts.map +1 -1
  271. package/dist/internal/hosting.js +7 -3
  272. package/dist/internal/init-interview.d.ts +3 -5
  273. package/dist/internal/init-interview.d.ts.map +1 -1
  274. package/dist/internal/init-interview.js +15 -88
  275. package/dist/internal/init-project.d.ts +13 -0
  276. package/dist/internal/init-project.d.ts.map +1 -1
  277. package/dist/internal/init-project.js +30 -37
  278. package/dist/internal/init-scaffold.d.ts +11 -0
  279. package/dist/internal/init-scaffold.d.ts.map +1 -1
  280. package/dist/internal/init-scaffold.js +47 -13
  281. package/dist/internal/interview/agent-questions.d.ts +19 -0
  282. package/dist/internal/interview/agent-questions.d.ts.map +1 -0
  283. package/dist/internal/interview/agent-questions.js +120 -0
  284. package/dist/internal/interview/question.d.ts +82 -0
  285. package/dist/internal/interview/question.d.ts.map +1 -0
  286. package/dist/internal/interview/question.js +198 -0
  287. package/dist/internal/local-control-plane.d.ts.map +1 -1
  288. package/dist/internal/local-control-plane.js +5 -1
  289. package/dist/internal/otel/collector.d.ts +2 -0
  290. package/dist/internal/otel/collector.d.ts.map +1 -1
  291. package/dist/internal/otel/collector.js +4 -0
  292. package/dist/internal/peer-connections.d.ts +6 -2
  293. package/dist/internal/peer-connections.d.ts.map +1 -1
  294. package/dist/internal/peer-connections.js +23 -19
  295. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  296. package/dist/internal/resolve-prod-target.js +2 -1
  297. package/dist/internal/sdk-runner.d.ts.map +1 -1
  298. package/dist/internal/sdk-runner.js +43 -16
  299. package/dist/internal/sdk-subagent-inherit-support.d.ts +9 -0
  300. package/dist/internal/sdk-subagent-inherit-support.d.ts.map +1 -0
  301. package/dist/internal/sdk-subagent-inherit-support.js +89 -0
  302. package/dist/internal/server.d.ts.map +1 -1
  303. package/dist/internal/server.js +6 -5
  304. package/dist/internal/session-engine.d.ts +13 -0
  305. package/dist/internal/session-engine.d.ts.map +1 -1
  306. package/dist/internal/session-engine.js +62 -11
  307. package/dist/internal/session-run-log.d.ts.map +1 -1
  308. package/dist/internal/session-run-log.js +26 -11
  309. package/dist/internal/{convert-automation/slug.d.ts → slug.d.ts} +4 -1
  310. package/dist/internal/slug.d.ts.map +1 -0
  311. package/dist/internal/{convert-automation/slug.js → slug.js} +11 -1
  312. package/dist/playground/assets/index-7fVUOA5l.css +1 -0
  313. package/dist/playground/assets/{index-ClxRl2Cw.js → index-U3TRnwAP.js} +43 -43
  314. package/dist/playground/index.html +2 -2
  315. package/dist/types.d.ts +26 -1
  316. package/dist/types.d.ts.map +1 -1
  317. package/docs/README.md +1 -1
  318. package/docs/building-with-agents.md +5 -5
  319. package/docs/deployment.md +70 -33
  320. package/docs/evals.md +1 -16
  321. package/docs/guides/cloud-agents.md +3 -9
  322. package/docs/guides/grokbot-agents.md +10 -14
  323. package/docs/guides/hooks.md +0 -1
  324. package/docs/guides/improve.md +4 -6
  325. package/docs/guides/mcp-oauth.md +18 -41
  326. package/docs/guides/webhooks.md +35 -18
  327. package/docs/quickstart.md +2 -2
  328. package/docs/reference/agent-config.md +26 -1
  329. package/docs/reference/channels.md +29 -13
  330. package/docs/reference/cli.md +115 -42
  331. package/docs/reference/connections.md +6 -5
  332. package/docs/reference/evals.md +15 -4
  333. package/docs/reference/hooks.md +0 -1
  334. package/docs/reference/http-api.md +7 -17
  335. package/docs/reference/playground.md +2 -5
  336. package/docs/reference/schedules.md +26 -3
  337. package/docs/reference/sessions.md +1 -2
  338. package/docs/reference/skills.md +1 -1
  339. package/docs/reference/tools.md +3 -29
  340. package/docs/templates/grokbot-agents.md +1 -1
  341. package/docs/troubleshooting.md +12 -7
  342. package/package.json +36 -35
  343. package/schemas/grokbot-answers.schema.json +343 -0
  344. package/skills/create-agent/SKILL.md +16 -11
  345. package/skills/debug/SKILL.md +3 -4
  346. package/skills/evals/SKILL.md +2 -2
  347. package/skills/framework-map/SKILL.md +10 -10
  348. package/skills/mcp-auth/SKILL.md +10 -34
  349. package/skills/migrate-v2/SKILL.md +13 -9
  350. package/skills/setup-slack/SKILL.md +0 -13
  351. package/templates/agentic-owners/bot/lib/owners/handles.ts +1 -1
  352. package/templates/agentic-owners/bot/lib/owners/matching.ts +20 -9
  353. package/templates/agents-md/README.md +3 -3
  354. package/templates/agents-md/bot/channels/queue.ts +3 -8
  355. package/templates/agents-md/bot/instructions.md +1 -2
  356. package/templates/agents-md/bot/tools/apply_agents.ts +0 -1
  357. package/templates/agents-md/evals/agents.eval.ts +2 -2
  358. package/templates/demo/bot/channels/queue.ts +5 -15
  359. package/templates/grokbot-agents/.gitignore +4 -0
  360. package/templates/pr-autofixer/bot/channels/drive.ts +3 -16
  361. package/templates/security-help/.gitignore +4 -0
  362. package/templates/triage/bot/channels/queue.ts +11 -22
  363. package/templates/triage/bot/channels/webhook.ts +3 -6
  364. package/templates/triage/bot/lib/parse-queue-event.ts +0 -6
  365. package/dist/docs/assets/chunks/@localSearchIndexroot.CzrtdJ8s.js +0 -1
  366. package/dist/docs/assets/chunks/channel.6ebHhoF9.js +0 -1
  367. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.BJ-CwKwu.js +0 -1
  368. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.BJ-CwKwu.js +0 -1
  369. package/dist/docs/assets/chunks/clone.DfV2fkWH.js +0 -1
  370. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DNdUCJyd.js +0 -1
  371. package/dist/docs/assets/chunks/wardley-RL74JXVD.C46G0P5a.js +0 -162
  372. package/dist/docs/assets/deployment.md.BYuEcDBv.js +0 -29
  373. package/dist/docs/assets/guides_cloud-agents.md.CWJjS9No.js +0 -10
  374. package/dist/docs/assets/guides_cloud-agents.md.CWJjS9No.lean.js +0 -1
  375. package/dist/docs/assets/guides_grokbot-agents.md.tD1smFhU.js +0 -16
  376. package/dist/docs/assets/guides_mcp-oauth.md.DR3zhC9r.lean.js +0 -1
  377. package/dist/docs/assets/reference_channels.md.LbNIJBwd.js +0 -23
  378. package/dist/docs/assets/reference_http-api.md.DbFNOubV.js +0 -11
  379. package/dist/docs/assets/reference_playground.md.1hx0gcIu.js +0 -1
  380. package/dist/docs/assets/reference_playground.md.1hx0gcIu.lean.js +0 -1
  381. package/dist/docs/assets/reference_sessions.md.CyM7ARz1.js +0 -1
  382. package/dist/docs/assets/reference_tools.md.DzIY9JzY.lean.js +0 -1
  383. package/dist/docs/assets/troubleshooting.md.x-GBa7wN.js +0 -1
  384. package/dist/internal/convert-automation/slug.d.ts.map +0 -1
  385. package/dist/playground/assets/index-BKSsuEMw.css +0 -1
  386. /package/dist/docs/assets/{guides_hooks.md.5Ce3NXxZ.lean.js → guides_hooks.md.B_bKG1oA.lean.js} +0 -0
  387. /package/dist/docs/assets/{index.md.Dxxr7pFa.lean.js → index.md.BIBHIQtU.lean.js} +0 -0
  388. /package/dist/docs/assets/{quickstart.md.BK5gjHM2.lean.js → quickstart.md.CduLGBAB.lean.js} +0 -0
  389. /package/dist/docs/assets/{reference_hooks.md.B-eGa2km.lean.js → reference_hooks.md.DbJC8mcZ.lean.js} +0 -0
  390. /package/dist/docs/assets/{reference_sessions.md.CyM7ARz1.lean.js → reference_sessions.md.C_uzIWuy.lean.js} +0 -0
  391. /package/dist/docs/assets/{reference_skills.md.ClkMoQsV.lean.js → reference_skills.md.C2GWh7g8.lean.js} +0 -0
  392. /package/dist/docs/assets/{templates_grokbot-agents.md.2sydjFiO.lean.js → templates_grokbot-agents.md.DgpPEs7B.lean.js} +0 -0
@@ -24,8 +24,8 @@ Give the coding agent a purpose and the surfaces people will use. The
24
24
  then scaffolds and verifies a small first version.
25
25
 
26
26
  > Use the BDK create-agent skill to build a PR triage agent
27
- > reachable through GitHub. It should summarize failed checks, require
28
- > approval before posting a review, and include one smoke eval.
27
+ > reachable through GitHub. It should summarize failed checks, post one
28
+ > review comment per pull request, and include one smoke eval.
29
29
 
30
30
  Ask it to read
31
31
  [`skills/create-agent/SKILL.md`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/skills/create-agent/SKILL.md). The
@@ -44,7 +44,7 @@ Examples:
44
44
  > skill, keep replies in the source thread, and verify one local mention.
45
45
 
46
46
  > Connect the private inventory MCP server with host OAuth. Keep its
47
- > write tools behind an approved server-tool wrapper.
47
+ > write tools behind a narrow server-tool wrapper.
48
48
 
49
49
  > Add a GitHub ready-for-review trigger and replay PR 42 before posting
50
50
  > anything live.
@@ -75,8 +75,8 @@ validation and exposes its real output.
75
75
  ## Verify one end-to-end turn
76
76
 
77
77
  Once deterministic inputs are correct, send the same request a user
78
- will. The coding agent should check the final answer, tool trajectory,
79
- and any parked approval before declaring the capability complete.
78
+ will. The coding agent should check the final answer and tool trajectory
79
+ before declaring the capability complete.
80
80
 
81
81
  ```text
82
82
  bdk run --dir . \
@@ -195,6 +195,18 @@ The source repository must be available through the team's repository
195
195
  integration, and a nested `--path` must contain an installable BDK
196
196
  project.
197
197
 
198
+ ### Privacy Mode
199
+
200
+ A hosted deployment stores a snapshot of its source repository, along
201
+ with the sessions, KV, files, and logs the agent creates for your team.
202
+ Whether you can deploy depends on the privacy setting that applies to
203
+ you, which is your team's setting when the team enforces one:
204
+
205
+ | Privacy setting | Managed hosting |
206
+ | --- | --- |
207
+ | Privacy Mode | Available. Cursor stores deployment data the same way it does without Privacy Mode, and the agent's model requests get the same Privacy Mode handling as your other Cursor requests. |
208
+ | Privacy Mode (Legacy) | Not available. `deploy` fails, because this setting doesn't let Cursor store code. |
209
+
198
210
  ## Add egress and secrets
199
211
 
200
212
  Declare the external hosts and secret names the agent needs. Mounted
@@ -242,54 +254,80 @@ platform can verify each delivery's signature before any compute starts.
242
254
  Enter egress hosts without schemes or paths. An HTTPS host needs no port;
243
255
  add one, as `clickhouse.example.com:9440`, only for a protocol the proxy
244
256
  reads no hostname from. The
245
- [Host MCP OAuth guide](/docs/guides/mcp-oauth.md) owns the extra secret and
246
- egress steps for OAuth-backed MCP servers.
257
+ [Host MCP OAuth guide](/docs/guides/mcp-oauth.md) covers OAuth-backed MCP
258
+ servers on a hosted agent.
247
259
 
248
260
  ## Use the hosted agent
249
261
 
250
262
  ### Verify a hosted turn
251
263
 
252
- Start a turn on the deployment:
264
+ After `deploy` reports `running`, message the deployment from the CLI:
253
265
 
254
- ```text
266
+ ```bash
255
267
  bdk run --prod --slug weather-agent \
256
268
  --message "Forecast for Paris"
257
269
  ```
258
270
 
259
- The command returns as soon as the deployment accepts the turn, so the output
260
- has a `deliveryId` but no `sessionId` yet. That's expected, with or without
261
- `--dry-run`. Open the deployment from **Deployed Agents** in the
262
- [dashboard](https://cursor.com/dashboard) and select **Sessions** to find the
263
- new session's `ses_...` ID.
271
+ The command returns as soon as the deployment accepts the turn, so its
272
+ output has a `deliveryId` and `workflowId` but no `sessionId` yet; the
273
+ session is created when the turn starts. Add `--dry-run` to check a
274
+ deployment without side effects: read tools run and write tools are
275
+ stubbed.
264
276
 
265
- Check the session from the CLI:
277
+ Find the new session in the deployment's recent output, which prints a
278
+ `==> ses_... (http) <==` header for each session, or open the deployment
279
+ from **Deployed Agents** in the [dashboard](https://cursor.com/dashboard)
280
+ and select **Sessions**:
266
281
 
267
- ```text
282
+ ```bash
283
+ bdk logs --prod --once --slug weather-agent
284
+ ```
285
+
286
+ Then follow the turn:
287
+
288
+ ```bash
268
289
  bdk session ses_... --prod --slug weather-agent
269
290
  ```
270
291
 
271
- While the turn runs, the command reports how many events have arrived and
272
- prints `Turn running; runs may lag behind events.` Rerun it until the latest
273
- run shows a final status such as `finished`. High-effort turns can take about
274
- eight minutes, and runs can stay empty until the turn ends, so a growing event
275
- count is the progress signal. Escalate only when no new events arrive for about
276
- two to three minutes.
292
+ The command lists each hosted run with its status and log lines. While
293
+ the turn is still working, it reports how many events have arrived and
294
+ prints `Turn running; runs may lag behind events.` Rerun it until the
295
+ latest run shows a final status such as `finished`. A high-effort turn
296
+ can take several minutes, and its run can show no logs until it ends, so
297
+ a growing event count is the progress signal.
277
298
 
278
- Hosted deployments don't support `bdk call` or `bdk sessions`, so use
279
- `bdk run --prod` and `bdk session` instead. Dashboard links to a single session
280
- may not open yet, so confirm the result with `bdk session`.
299
+ To continue the same conversation, pass `--session ses_...` to
300
+ `run --prod`. `bdk playground --prod --slug weather-agent --session ses_...`
301
+ opens the session in the dashboard playground. Hosted deployments don't
302
+ support `bdk chat`, `call`, `sessions`, `cost`, or `mcp`; use
303
+ `run --prod`, `logs --prod`, and `session --prod` instead.
281
304
 
282
- ### Call the hosted HTTP API
305
+ ### Send work to the deployment
283
306
 
284
- External HTTP clients use the stable alias URL and send the alias token
285
- on every request:
307
+ A hosted agent wakes from its channels: Slack mentions and DMs, SCM
308
+ events, and custom channel routes. External HTTP clients call a custom
309
+ route on the stable alias URL and send the alias token on every
310
+ request:
286
311
 
287
312
  ```bash
288
- curl "$AGENT_ALIAS_URL/v1/health" \
289
- -H "X-Agent-Alias-Token: $AGENT_ALIAS_TOKEN"
313
+ curl -X POST "$AGENT_ALIAS_URL/v1/channels/tickets/ticket" \
314
+ -H "X-Agent-Alias-Token: $AGENT_ALIAS_TOKEN" \
315
+ -H 'content-type: application/json' \
316
+ -d '{"ticketId":"ENG-142","message":"CSV export returns 500"}'
290
317
  ```
291
318
 
292
- The first deploy prints this token once. Store it outside terminal
319
+ The deployment answers `202 Accepted` with an empty body as soon as the
320
+ request arrives, then runs the route's handler, so the caller never
321
+ receives a session ID or a result. Deliver results from the channel, as
322
+ described in [Route responses](/docs/reference/channels.md#route-responses).
323
+
324
+ To confirm the work started, find the new session with
325
+ `bdk logs --prod` and follow it with `bdk session --prod`, as in
326
+ [Verify a hosted turn](#verify-a-hosted-turn).
327
+
328
+ ### Protect the alias token
329
+
330
+ The first deploy prints the alias token once. Store it outside terminal
293
331
  transcripts; it cannot be retrieved later. If it is lost or exposed,
294
332
  `bdk rotate-token weather-agent` replaces it and invalidates the
295
333
  old value.
@@ -327,9 +365,8 @@ across normal runtime replacements. Files written elsewhere on the
327
365
  runtime's local filesystem are disposable; use `ctx.host.kv` or
328
366
  `ctx.host.files` for durable application state.
329
367
 
330
- Parked approvals and in-memory reminder handlers do not survive a
331
- restart. Run the turn again or recreate the reminder after a
332
- replacement.
368
+ On architecture v2, the default, reminders take a prompt or a named
369
+ handler. See [Reminders](/docs/reference/schedules.md#reminders).
333
370
 
334
371
  ## Self-host securely
335
372
 
@@ -371,8 +408,8 @@ per-caller and channel-specific auth.
371
408
 
372
409
  ## Observability
373
410
 
374
- Use `bdk session <sessionId> --prod` for a hosted session's runs and logs,
375
- [OpenTelemetry](/docs/guides/opentelemetry.md) for traces and metrics, and
411
+ Use `bdk logs --prod` and `bdk session <sessionId> --prod` for a hosted
412
+ session's runs and logs, [OpenTelemetry](/docs/guides/opentelemetry.md) for traces and metrics, and
376
413
  [session traces](/docs/reference/sessions.md#inspect-a-saved-event-stream)
377
414
  for a local conversation.
378
415
 
@@ -385,8 +422,8 @@ for a local conversation.
385
422
  - [GitHub](/docs/guides/github.md): Cursor-event repositories and direct
386
423
  webhook delivery
387
424
  - [Slack](/docs/guides/slack.md): provision a dedicated hosted Slack app
388
- - [Host MCP OAuth](/docs/guides/mcp-oauth.md): persist OAuth credentials
389
- across hosted replacements
425
+ - [Host MCP OAuth](/docs/guides/mcp-oauth.md): reach OAuth-backed MCP
426
+ servers from a hosted agent
390
427
  - [Troubleshooting](/docs/troubleshooting.md): diagnose failed or stale
391
428
  deployments
392
429
 
@@ -485,7 +522,7 @@ Configure the judge model in `evals.config.ts`. The
485
522
  [Evals reference](/docs/reference/evals.md#judges) owns grader options and
486
523
  severity rules.
487
524
 
488
- ## Test a conversation or approval
525
+ ## Test a conversation
489
526
 
490
527
  Several `t.send` calls in one case share a session. Assertions on a
491
528
  returned turn inspect only that turn, while assertions on `t` inspect
@@ -501,21 +538,6 @@ t.check(followUp.message, includes(/blocker/i));
501
538
  t.succeeded();
502
539
  ```
503
540
 
504
- For a tool that requires approval, the expected result is a parked turn
505
- instead of a completed one:
506
-
507
- ```ts
508
- await t.send("Apply the approved policy update.");
509
- t.parked();
510
- t.calledTool("apply_policy", {
511
- input: { verdict: "update" },
512
- });
513
- ```
514
-
515
- Pair an approval case with a safe branch that calls
516
- `t.notCalledTool("apply_policy")`, so both sides of the decision stay
517
- protected.
518
-
519
541
  ## Pin realistic inputs
520
542
 
521
543
  A useful eval changes only when the agent changes. Freeze canonical chat
@@ -1124,16 +1146,13 @@ export default cursorCloudAgents({
1124
1146
  repos: [{ url: "https://github.com/acme/api", startingRef: "main" }],
1125
1147
  autoCreatePR: true,
1126
1148
  },
1127
- needsApproval: true,
1128
1149
  });
1129
1150
  ```
1130
1151
 
1131
1152
  Launches run under the host's signed-in account (`bdk login`,
1132
1153
  `CURSOR_API_KEY`, or `CURSOR_SERVICE_ACCOUNT_KEY`) and spend its
1133
- cloud-agent budget. Name the repositories the agent may target, and
1134
- keep approval on when you can't.
1135
-
1136
- Launch approval resolves through the serving host.
1154
+ cloud-agent budget. Name the repositories the agent may target in
1155
+ `cloud.repos`.
1137
1156
 
1138
1157
  ## What the agent can do
1139
1158
 
@@ -1171,7 +1190,6 @@ their own.
1171
1190
  | `cloud` | Launch defaults for repositories, environment, and pull request behavior. |
1172
1191
  | `cloud.repos` | The repositories the agent may hand work to, with a default branch or pull request for each. Without it, launches run with no repository and the model can't name one, so secrets in `cloud.envVars` never reach a repository you didn't list. |
1173
1192
  | `model` | The model launched agents run. Omit it to use the account default. |
1174
- | `needsApproval` | Park launches and follow-ups for a [human decision](/docs/reference/tools.md#gate-a-tool-on-human-approval). Defaults to `true` when no `cloud.repos` are configured, `false` otherwise. |
1175
1193
  | `apiKey` | A Cursor API key to launch with instead of the host's own. |
1176
1194
 
1177
1195
 
@@ -1189,8 +1207,6 @@ Continue with these pages:
1189
1207
 
1190
1208
  - [Extensions](/docs/reference/extensions.md): how mounts, namespaces, and
1191
1209
  overrides work
1192
- - [Gate a tool on human approval](/docs/reference/tools.md#gate-a-tool-on-human-approval):
1193
- where parked launches get approved
1194
1210
 
1195
1211
  ---
1196
1212
 
@@ -2075,9 +2091,8 @@ it does not move this agent onto a Grok Bot runtime.
2075
2091
 
2076
2092
  ## Mount it
2077
2093
 
2078
- List the bots your agent may contact and decide whether each new message
2079
- needs approval. Descriptions teach the model when to choose one bot over
2080
- another.
2094
+ List the bots your agent may contact. Descriptions teach the model when
2095
+ to choose one bot over another.
2081
2096
 
2082
2097
  ```ts
2083
2098
  // bot/extensions/grokbot.ts
@@ -2094,7 +2109,6 @@ export default cursorGrokBotAgents({
2094
2109
  description: "Routes work and tracks priorities.",
2095
2110
  },
2096
2111
  ],
2097
- needsApproval: true,
2098
2112
  });
2099
2113
  ```
2100
2114
 
@@ -2111,8 +2125,8 @@ bdk init ./grokbot --template grokbot-agents
2111
2125
  ## Ask a named bot
2112
2126
 
2113
2127
  When someone says, "Ask Plan Keeper whether we should move the picnic,"
2114
- your agent prepares one self-contained message, requests approval, and
2115
- waits for the bot's delivered reply. That reply appears in the current
2128
+ your agent prepares one self-contained message, sends it, and waits for
2129
+ the bot's delivered reply. That reply appears in the current
2116
2130
  conversation as the consultation result.
2117
2131
 
2118
2132
  The message must include who is asking, the relevant facts, and the
@@ -2149,9 +2163,9 @@ existing memory.
2149
2163
  > Stop Plan Keeper's current turn. Then ask it to compare indoor venues
2150
2164
  > instead of changing the time.
2151
2165
 
2152
- Only `ask` uses `needsApproval`. `check` and `interrupt` execute without
2153
- an approval card, so expose this extension only to callers who may read
2154
- or stop those bot conversations.
2166
+ `check` and `interrupt` act on the bot conversation directly, so expose
2167
+ this extension only to callers who may read or stop those
2168
+ conversations.
2155
2169
 
2156
2170
  ## Configure it
2157
2171
 
@@ -2160,8 +2174,8 @@ list is refused, but a misspelled configured name may create a new empty
2160
2174
  bot on first use. If a result says `created: true`, tell the person and
2161
2175
  check the name before sending more work.
2162
2176
 
2163
- With no `agents` list, any name is allowed and approval defaults on.
2164
- Prefer an explicit list for a shared agent. `list` returns configured
2177
+ With no `agents` list, any name is allowed. Prefer an explicit list for
2178
+ a shared agent. `list` returns configured
2165
2179
  bots and bots this caller already contacted; it does not enumerate the
2166
2180
  whole account.
2167
2181
 
@@ -2200,8 +2214,6 @@ directory and disable that tool. See
2200
2214
 
2201
2215
  - [Extensions](/docs/reference/extensions.md): namespaces, trust, and
2202
2216
  overlays
2203
- - [Tool approvals](/docs/reference/tools.md#gate-a-tool-on-human-approval):
2204
- approve asks
2205
2217
 
2206
2218
  ---
2207
2219
 
@@ -2302,7 +2314,6 @@ replay recorded events into hooks.
2302
2314
  | --- | --- |
2303
2315
  | Add context before the model | `instructions.md`, skills, or `workspaceFiles` |
2304
2316
  | Deliver to Slack or a PR | Channel [`events`](/docs/reference/channels.md#events) or packs |
2305
- | Block or approve a tool | [`needsApproval`](/docs/reference/tools.md#gate-a-tool-on-human-approval) |
2306
2317
  | Gate final assistant text | `defineResult` |
2307
2318
  | Gate behavior | [Evals](/docs/evals.md) |
2308
2319
 
@@ -2335,9 +2346,8 @@ deployed.
2335
2346
 
2336
2347
  ## Mount it
2337
2348
 
2338
- Mount Cloud agents with the agent's own repository allowlisted, keep
2339
- launch approval explicit, then mount `improve` with the source
2340
- directory.
2349
+ Mount Cloud agents with the agent's own repository allowlisted, then
2350
+ mount `improve` with the source directory.
2341
2351
 
2342
2352
  ```ts
2343
2353
  // bot/extensions/cloud.ts
@@ -2353,7 +2363,6 @@ export default cursorCloudAgents({
2353
2363
  ],
2354
2364
  autoCreatePR: true,
2355
2365
  },
2356
- needsApproval: true,
2357
2366
  });
2358
2367
  ```
2359
2368
 
@@ -2388,8 +2397,8 @@ a narrow behavior request into an unrelated refactor.
2388
2397
 
2389
2398
  ## Follow the source change
2390
2399
 
2391
- The agent requests approval and launches one cloud agent on the
2392
- configured repository and ref. It reports the complete cloud-agent ID
2400
+ The agent launches one cloud agent on the configured repository and
2401
+ ref. It reports the complete cloud-agent ID
2393
2402
  and URL immediately, then checks the same run instead of launching
2394
2403
  another agent for follow-up work.
2395
2404
 
@@ -2807,9 +2816,7 @@ retries and the turn continues without restarting the agent.
2807
2816
  bdk serve --dir . --dev
2808
2817
  ```
2809
2818
 
2810
- Connect authorizes the process that is running now. It does not seed
2811
- credentials for a future hosted replacement; use `--store` for that
2812
- separate outcome.
2819
+ Connect authorizes the process that is running now.
2813
2820
 
2814
2821
  ## Keep privileged tools behind a wrapper
2815
2822
 
@@ -2855,43 +2862,22 @@ export default defineTool({
2855
2862
  ```
2856
2863
 
2857
2864
  The model sees `get_stock`, not the unrestricted inventory server.
2858
- Use this shape when code should own an allowlist, approval, or other
2859
- side-effect gate.
2860
-
2861
- ## Keep OAuth across hosted replacements
2862
-
2863
- Declare the server's egress domain and the OAuth secret names, authorize
2864
- from a signed-in machine, then store the credentials and redeploy. The
2865
- next hosted process can reconnect without opening a browser.
2866
-
2867
- ```ts
2868
- // bot/agent.ts
2869
- export default defineAgent({
2870
- hosting: {
2871
- egressDomains: ["mcp.example.com"],
2872
- secretNames: [
2873
- "MCP_OAUTH_INVENTORY_ACCESS_TOKEN",
2874
- "MCP_OAUTH_INVENTORY_REFRESH_TOKEN",
2875
- "MCP_OAUTH_INVENTORY_CLIENT_ID",
2876
- ],
2877
- },
2878
- });
2879
- ```
2865
+ Use this shape when code should own an allowlist or another side-effect
2866
+ gate.
2880
2867
 
2881
- ```text
2882
- bdk mcp oauth inventory --store
2883
- bdk secrets list my-agent
2884
- bdk deploy
2885
- ```
2868
+ ## Use an OAuth server from a hosted agent
2886
2869
 
2887
- `--store` writes deployment secrets; it does not restart the current
2888
- process. Follow the CLI or dashboard prompt to redeploy, then exercise
2889
- the hosted agent.
2870
+ Tokens from `mcp oauth` stay in the CLI config directory of the machine
2871
+ that authorized them, so a hosted deployment doesn't receive them. For a
2872
+ Cursor-managed agent, add the server under MCP in the Cursor dashboard,
2873
+ reach it through a
2874
+ [`cursorAccount: true` connection](/docs/reference/connections.md#cursor-account-mcp-connection),
2875
+ and connect it from **Deployed Agents** in the
2876
+ [dashboard](https://cursor.com/dashboard).
2890
2877
 
2891
- These credentials belong to the deployment, not to the person who
2892
- clicked Connect. Anyone able to use that agent can reach the MCP
2893
- capabilities you expose, so keep privileged servers host-only or narrow
2894
- their tool list.
2878
+ Anyone able to use that agent can reach the MCP capabilities you
2879
+ expose, so narrow the connection's `servers` list and keep privileged
2880
+ operations behind a host-side wrapper.
2895
2881
 
2896
2882
  ## Choose where credentials live
2897
2883
 
@@ -2900,8 +2886,8 @@ Use the credential shape that matches who should own access:
2900
2886
  - Choose `cursorAccount: true` for connectors already authorized under
2901
2887
  MCP in the Cursor dashboard. Their tokens stay on the Cursor backend.
2902
2888
 
2903
- - Choose `url` with `oauth: true` when the serve host or hosted
2904
- deployment should hold OAuth credentials.
2889
+ - Choose `url` with `oauth: true` when the machine running `bdk serve`
2890
+ should hold OAuth credentials.
2905
2891
 
2906
2892
  - Choose `url` with static `headers` when the server uses an API key or
2907
2893
  bearer token instead of OAuth.
@@ -2918,7 +2904,7 @@ caller needs a different downstream identity.
2918
2904
  connectors, per-session auth, and tool filtering
2919
2905
  - [CLI reference](/docs/reference/cli.md#mcp-oauth): OAuth command flags
2920
2906
  and browser callback behavior
2921
- - [Deployment](/docs/deployment.md): hosted secrets and egress
2907
+ - [Deployment](/docs/deployment.md): hosted egress and secrets
2922
2908
  - [Troubleshooting](/docs/troubleshooting.md): authorization symptoms and
2923
2909
  remedies
2924
2910
 
@@ -3496,9 +3482,9 @@ Author `bot/channels/<id>.ts`. Its routes mount under
3496
3482
  ## Receive a webhook and send the answer back
3497
3483
 
3498
3484
  When a ticket system sends a new message, this endpoint responds with
3499
- `202 Accepted` right away. The agent keeps working after the HTTP
3500
- request ends, and its completed answer appears as a comment on the
3501
- ticket.
3485
+ `202 Accepted` and an empty body right away. The agent keeps working
3486
+ after the HTTP request ends, and its completed answer appears as a
3487
+ comment on the ticket.
3502
3488
 
3503
3489
  ```ts
3504
3490
  // bot/channels/tickets.ts
@@ -3526,7 +3512,7 @@ export default defineChannel<TicketState>({
3526
3512
  title: `Ticket ${body.ticketId}`,
3527
3513
  })
3528
3514
  );
3529
- return Response.json({ accepted: true }, { status: 202 });
3515
+ return new Response(null, { status: 202 });
3530
3516
  },
3531
3517
  }),
3532
3518
  ],
@@ -3545,6 +3531,12 @@ export default defineChannel<TicketState>({
3545
3531
  SDK. Keeping that write in the event handler means the webhook request
3546
3532
  does not stay open while the model works.
3547
3533
 
3534
+ The caller only ever receives that empty `202`. On Cursor-managed
3535
+ hosting, the deployment sends it before your handler runs and discards
3536
+ whatever the handler returns, so deliver every result, including
3537
+ failures, back through the provider's API. See
3538
+ [Route responses](/docs/reference/channels.md#route-responses).
3539
+
3548
3540
  ## Keep one conversation per ticket
3549
3541
 
3550
3542
  Without a conversation key, every delivery creates a new session. Add
@@ -3578,10 +3570,11 @@ handler: async (_request, { callTool, send, waitUntil, body }) => {
3578
3570
  ticketId: body.ticketId,
3579
3571
  });
3580
3572
  if (prepared.isError) {
3581
- return Response.json(
3582
- { error: prepared.errorMessage ?? "Could not prepare ticket" },
3583
- { status: 502 }
3573
+ await postTicketComment(
3574
+ body.ticketId,
3575
+ "I couldn't load this ticket, so I didn't draft a reply."
3584
3576
  );
3577
+ return new Response(null, { status: 202 });
3585
3578
  }
3586
3579
 
3587
3580
  waitUntil(
@@ -3593,17 +3586,19 @@ handler: async (_request, { callTool, send, waitUntil, body }) => {
3593
3586
  },
3594
3587
  })
3595
3588
  );
3596
- return Response.json({ accepted: true }, { status: 202 });
3589
+ return new Response(null, { status: 202 });
3597
3590
  },
3598
3591
  ```
3599
3592
 
3600
3593
  The same `message.completed` handler from the first example delivers
3601
- the answer back to the ticket.
3594
+ the answer back to the ticket. When preparation fails, the handler
3595
+ reports that on the ticket instead.
3602
3596
 
3603
3597
  ## Routes receive, events deliver
3604
3598
 
3605
3599
  Routes own inbound HTTP. A route validates the request, decides whether
3606
- to start or resume a turn, and responds to the caller. The channel's
3600
+ to start or resume a turn, and acknowledges the caller with `202`. The
3601
+ channel's
3607
3602
  `events` handlers receive session events later, which is where you
3608
3603
  deliver the model's answer or report a failure to the originating
3609
3604
  system.
@@ -3631,9 +3626,10 @@ route:
3631
3626
  - `callTool` runs an authored server tool without starting a model
3632
3627
  turn.
3633
3628
 
3634
- - `waitUntil` keeps background work alive after the HTTP response. Await
3635
- `send` when the caller needs the session handle, then call
3636
- `session.waitForCompletion()` if it also needs the turn outcome.
3629
+ - `waitUntil` keeps background work alive after the handler returns.
3630
+ Await `send` when later handler code needs the session handle, such
3631
+ as calling `session.waitForCompletion()` before reporting the turn
3632
+ outcome to the provider.
3637
3633
 
3638
3634
  - `host` provides authenticated services for API calls made by channel
3639
3635
  code.
@@ -3669,17 +3665,24 @@ export default defineChannel({
3669
3665
  const rawBody = await request.text();
3670
3666
  const signature = request.headers.get("x-provider-signature");
3671
3667
  if (!verifyProviderSignature(rawBody, signature)) {
3672
- return Response.json({ ok: false }, { status: 401 });
3668
+ return new Response(null, { status: 202 });
3673
3669
  }
3674
3670
 
3675
3671
  // Parse and dispatch only after the signature passes.
3676
- return Response.json({ ok: true });
3672
+ return new Response(null, { status: 202 });
3677
3673
  },
3678
3674
  }),
3679
3675
  ],
3680
3676
  });
3681
3677
  ```
3682
3678
 
3679
+ Because a hosted handler runs after the `202`, a delivery with a bad
3680
+ signature is dropped silently rather than rejected. When the provider
3681
+ sends a shared secret header or signs the raw body with HMAC-SHA256,
3682
+ use `sharedSecretAuth()` or `hmacSignatureAuth()` instead. Hosting
3683
+ checks those policies before the handler runs and answers a bad
3684
+ delivery with `401`.
3685
+
3683
3686
  `publicEndpoint()` only opens this channel's routes. The built-in
3684
3687
  session and tool APIs stay private. See
3685
3688
  [Auth policies](/docs/reference/channels.md#auth-policies) for bearer
@@ -3688,9 +3691,9 @@ tokens and the complete policy reference.
3688
3691
  ## Test locally
3689
3692
 
3690
3693
  Run the agent in development mode, then replay the same payload the
3691
- provider will send. The response should return immediately, and the
3692
- resulting session should appear in the playground while the reply is
3693
- delivered.
3694
+ provider will send. The route should answer `202` with an empty body
3695
+ right away, and the resulting session should appear in the playground
3696
+ while the reply is delivered.
3694
3697
 
3695
3698
  ```text
3696
3699
  bdk serve --dir . --dev
@@ -3864,7 +3867,7 @@ Source: /docs/index.md
3864
3867
 
3865
3868
  The Grok Bot Development Kit (BDK) lets you define, test, and deploy agents
3866
3869
  as code. It uses the Cursor SDK harness that powers Bugbot, Security Review,
3867
- and Approval Bot.
3870
+ Approval Bot, and Rollouts.
3868
3871
 
3869
3872
  A BDK project is a folder of Markdown and TypeScript. Combine deterministic
3870
3873
  code with model judgment, then make the bot or agent available in source
@@ -4273,8 +4276,8 @@ trigger, both tool calls, and the verdict.
4273
4276
 
4274
4277
  - [Evals](/docs/evals.md): freeze these two PRs as regression checks so
4275
4278
  prompt changes can't flip a verdict
4276
- - [Tools](/docs/reference/tools.md): more on typed tools, approvals, and
4277
- direct calls
4279
+ - [Tools](/docs/reference/tools.md): more on typed tools, dry-run effects,
4280
+ and direct calls
4278
4281
  - [GitHub](/docs/guides/github.md): fixtures, forwarding, and pulling
4279
4282
  events from Cursor
4280
4283
  - [Building agents with agents](/docs/building-with-agents.md): have a
@@ -4313,7 +4316,8 @@ export default defineAgent({
4313
4316
  | `description` | string | What the agent is for. Required on subagents; the parent model reads it to decide when to delegate. Documentation-only on the root. |
4314
4317
  | `instructions` | string | Inline instructions. Prefer `instructions.md`; this exists for subagents and generated configs. |
4315
4318
  | `local` | `{ cwd?, workspaceDir?, sandbox? }` | Local harness defaults. See [Local options](#local-options). |
4316
- | `hosting` | `{ egressDomains?, secretNames? }` | Managed-hosting declarations read by `bdk deploy`: the deployment's egress allowlist and the secret names the agent expects. Mounted [extensions](/docs/reference/extensions.md#build-an-extension) add their own. Ignored by local serving. |
4319
+ | `persistent` | boolean | Keep one long-lived runtime for the hosted deployment. Defaults to `false`. See [Persistent hosting](#persistent-hosting). |
4320
+ | `hosting` | `{ egressDomains?, secretNames?, image? }` | Managed-hosting declarations read by `bdk deploy`: the deployment's egress allowlist, the secret names the agent expects, and a container image for a [persistent agent](#persistent-hosting). Mounted [extensions](/docs/reference/extensions.md#build-an-extension) add their own. Ignored by local serving. |
4317
4321
  | `concurrency` | `{ maxRunningTurns? }` | Agent-wide concurrent turn limit. See [Concurrency](#concurrency). |
4318
4322
  | `builtinTools` | `{ reminders? }` | Framework-provided model-facing tools, opted in per capability. See [Built-in tools](#built-in-tools). |
4319
4323
  | `tools` | `ToolName[]` | Allowlist of built-in harness tools offered to the model. Unset = the model's full standard toolset. See [Harness tools](#harness-tools). |
@@ -4370,6 +4374,30 @@ does not leak rules, skills, or MCP servers into the turn. A standalone git
4370
4374
  root keeps the in-project session workspace. Point `cwd` at a checkout only
4371
4375
  when the agent should inherit that tree.
4372
4376
 
4377
+ ## Persistent hosting
4378
+
4379
+ By default, a hosted deployment starts a runtime when an event arrives
4380
+ and stops it when the work ends. Set `persistent: true` to keep one
4381
+ long-lived runtime for the deployment instead, with its state directory
4382
+ on the runtime's own disk. On a redeploy, the new version starts beside
4383
+ the old one on the same state, and the old version stops after the new
4384
+ one takes over. Each team can have one persistent deployment. Local
4385
+ serving ignores the flag.
4386
+
4387
+ ```ts
4388
+ export default defineAgent({
4389
+ persistent: true,
4390
+ hosting: { image: "incident-bot-base" },
4391
+ });
4392
+ ```
4393
+
4394
+ `hosting.image` names a container image that your team pushed with
4395
+ `bdk images push`. The agent runs inside that image instead of the
4396
+ default Node 22 image. Only persistent agents can use it, and `deploy`
4397
+ rejects `hosting.image` on any other agent. A deploy pins the image it
4398
+ finds, so after you push a new image under the same name, deploy again
4399
+ to pick it up.
4400
+
4373
4401
  ## Harness tools
4374
4402
 
4375
4403
  Use `tools` to limit which built-in Cursor harness tools the model can
@@ -4601,8 +4629,8 @@ available alongside any custom or prebuilt channels.
4601
4629
 
4602
4630
  ## Built-in HTTP channel
4603
4631
 
4604
- The built-in channel serves the session, approval, tool, discovery, and
4605
- health routes. In a multi-agent host, each agent's routes sit under its
4632
+ The built-in channel serves the session, tool, and discovery routes. In
4633
+ a multi-agent host, each agent's routes sit under its
4606
4634
  slug. See the [HTTP API](/docs/reference/http-api.md) for request and response
4607
4635
  contracts.
4608
4636
 
@@ -4622,14 +4650,13 @@ export default defineChannel({
4622
4650
  message: z.string(),
4623
4651
  prUrl: z.string().url(),
4624
4652
  }),
4625
- handler: async (_request, { send, body }) => {
4626
- const session = await send(
4627
- `${body.message}\n\nPull request: ${body.prUrl}`,
4628
- {
4653
+ handler: async (_request, { send, waitUntil, body }) => {
4654
+ waitUntil(
4655
+ send(`${body.message}\n\nPull request: ${body.prUrl}`, {
4629
4656
  continuationToken: `pr:${body.prUrl}`,
4630
- }
4657
+ })
4631
4658
  );
4632
- return Response.json({ sessionId: session.id });
4659
+ return new Response(null, { status: 202 });
4633
4660
  },
4634
4661
  }),
4635
4662
  ],
@@ -4640,6 +4667,23 @@ The route above is
4640
4667
  `POST /v1/channels/<id>/review`. Calls for the same pull request reuse
4641
4668
  one conversation because they pass the same continuation token.
4642
4669
 
4670
+ ## Route responses
4671
+
4672
+ A custom route acknowledges the caller and nothing more. On
4673
+ Cursor-managed hosting, the deployment answers every custom route with
4674
+ `202 Accepted` and an empty body as soon as the request arrives, then
4675
+ runs the handler. The caller never receives the handler's `Response`,
4676
+ so a route can't return a session ID, a computed result, or an error
4677
+ status. Requests rejected before the handler runs, such as a missing
4678
+ alias token or a failed `sharedSecretAuth` or `hmacSignatureAuth`
4679
+ check, still get `401`.
4680
+
4681
+ Deliver results through the channel's [`events`](#events) handlers, a
4682
+ callback to the system that sent the request, or a tool the turn calls.
4683
+ Local `serve` passes the handler's response through, so return
4684
+ `new Response(null, { status: 202 })` to keep local calls matching
4685
+ hosted ones.
4686
+
4643
4687
  ## Route verbs and schemas
4644
4688
 
4645
4689
  Route paths must begin with `/`. The method helper determines which Zod
@@ -4653,8 +4697,9 @@ schemas the route accepts:
4653
4697
 
4654
4698
  Plain JSON Schema objects don't type-check. Use `z.object({})` or
4655
4699
  `z.unknown()` for an open surface. The host validates the body and query
4656
- before calling the handler, returning `400` on failure; an empty body is
4657
- read as `{}`. Declared schemas also appear in `GET /v1/info` for
4700
+ before calling the handler, and an empty body is read as `{}`. A request
4701
+ that fails validation never reaches the handler; local `serve` answers it
4702
+ with `400`, while a hosted caller has already received its `202`. Declared schemas also appear in `GET /v1/info` for
4658
4703
  playground requests and slash commands.
4659
4704
 
4660
4705
  ## Handler arguments
@@ -4671,7 +4716,7 @@ Each handler receives the Fetch `Request` and a typed arguments object.
4671
4716
  | `auth` | The `AuthContext` returned by the route's auth chain |
4672
4717
  | `requestIp` | The TCP peer address, or `null` |
4673
4718
  | `host` | Shared MCP, provider, storage, telemetry, and reminder services |
4674
- | `waitUntil(promise)` | Track work after the response returns |
4719
+ | `waitUntil(promise)` | Keep work running after the handler returns |
4675
4720
  | `sessionUrls(request, sessionId)` | Build absolute playground and trace URLs for this mount |
4676
4721
  | `artifacts` | List or tag [artifacts](/docs/reference/artifacts.md); pass `sessionId` when attributing one |
4677
4722
 
@@ -4723,7 +4768,6 @@ transport controls:
4723
4768
  | `hasContinuationSession(token)` | Check whether a token maps to a session |
4724
4769
  | `isContinuationBusy(token)` | Check whether a turn is active for a token |
4725
4770
  | `interruptContinuation(token)` | Stop the active turn and clear queued coalesced follow-ups |
4726
- | `resolveApproval(...)` | Approve or deny a parked tool call |
4727
4771
 
4728
4772
  ## Auth policies
4729
4773
 
@@ -4762,7 +4806,7 @@ author their own chain, and `--allow-anonymous` swaps it for
4762
4806
 
4763
4807
  | Import | Function | Surface |
4764
4808
  | --- | --- | --- |
4765
- | `@cursor/bdk/channels/slack` | `slackChannel()` | Slack messages, threads, streaming replies, and approvals. See [Slack](/docs/guides/slack.md) |
4809
+ | `@cursor/bdk/channels/slack` | `slackChannel()` | Slack messages, threads, and streaming replies. See [Slack](/docs/guides/slack.md) |
4766
4810
  | `@cursor/bdk/channels/github` | `githubChannel()` | GitHub and GitHub Enterprise webhooks. See [GitHub](/docs/guides/github.md) |
4767
4811
  | `@cursor/bdk/channels/gitlab` | `gitlabChannel()` | GitLab.com and self-managed GitLab hooks. See [GitLab](/docs/guides/gitlab.md) |
4768
4812
  | `@cursor/bdk/channels/bitbucket` | `bitbucketChannel()` | Bitbucket Cloud and Data Center hooks. See [Bitbucket](/docs/guides/bitbucket.md) |
@@ -4857,12 +4901,17 @@ provide their own `help` subcommands.
4857
4901
  | [`deployments`](#deployments) | List deployments |
4858
4902
  | [`deployment`](#deployment) | Inspect one deployment |
4859
4903
  | [`stop`](#stop) | Stop a deployment |
4904
+ | [`start`](#start) | Start a stopped deployment |
4905
+ | [`kill`](#kill) | Stop a deployment, cancel its runs, and lock deploys |
4906
+ | [`unlock-deploys`](#unlock-deploys) | Let a killed deployment deploy again |
4860
4907
  | [`cancel-runs`](#cancel-runs) | Cancel active runs and reminder wakes |
4861
4908
  | [`event-repos`](#event-repos) | Replace a deployment's event repositories |
4862
4909
  | [`upgrade`](#upgrade) | Move a deployment to a release |
4910
+ | [`rollback`](#rollback) | Move a deployment to an earlier release |
4863
4911
  | [`delete`](#delete) | Delete a deployment |
4864
4912
  | [`rotate-token`](#rotate-token) | Replace a deployment's alias token |
4865
4913
  | [`secrets`](#secrets) | Set, list, or remove deployment secrets |
4914
+ | [`images`](#images) | Push, list, or remove container images for persistent agents |
4866
4915
 
4867
4916
  ### Connection and channel commands
4868
4917
 
@@ -4885,7 +4934,7 @@ Commands that send requests support these targets:
4885
4934
  | Ephemeral local server | Omit `--url` and `--prod` | `run`, `call`, `skill`, `eval` |
4886
4935
  | Running server | Pass `--url <baseUrl>` | `chat`, `resume`, `run`, `call`, `skill`, `eval`, `logs`, `sessions`, `session`, `cost`, `playground`, `mcp` |
4887
4936
  | Default local server | Omit `--url` and `--prod`; uses `http://127.0.0.1:3000` | `chat`, `resume`, `logs`, `sessions`, `session`, `cost`, `playground` |
4888
- | Hosted deployment | Pass `--prod` | `run`, `session`, `playground` |
4937
+ | Hosted deployment | Pass `--prod` | `run`, `session`, `logs`, `playground` |
4889
4938
 
4890
4939
  An explicit `--url` must include the slug for a multi-agent server, such as
4891
4940
  `http://127.0.0.1:3000/pr-approver`. `--slug` never changes an explicit URL.
@@ -4895,8 +4944,8 @@ An explicit `--url` must include the slug for a multi-agent server, such as
4895
4944
  | --- | --- |
4896
4945
  | `--dir <path>` | Select the project root. The default is the current directory. |
4897
4946
  | `--url <baseUrl>` | Use a running agent instead of local project discovery. |
4898
- | `--prod` | Use the hosted deployment. Only `run`, `session`, and `playground` accept it. |
4899
- | `--slug <slug>` | Select an agent from a multi-agent project or a hosted resource. Under `--prod`, the default is the `--dir` basename. |
4947
+ | `--prod` | Use the hosted deployment. Only `run`, `session`, `logs`, and `playground` accept it; `chat`, `resume`, `call`, `skill`, `sessions`, `cost`, and `mcp` report that the deployment doesn't support the command, and `eval` rejects the flag. |
4948
+ | `--slug <slug>` | Select an agent from a multi-agent project or a hosted deployment. Under `--prod`, the default is the `--dir` basename. |
4900
4949
  | `--team <id>` | Select a Cursor team. The signed-in account's team is the default. |
4901
4950
  | `--api-key <key>` | Override the Cursor credential for commands that authenticate with Cursor. |
4902
4951
  | `--bearer-token <token>` | Authenticate to a running server with a bearer token. |
@@ -5021,28 +5070,31 @@ bdk run [--dir <path>] [--message <text>]...
5021
5070
 
5022
5071
  | Option | Contract |
5023
5072
  | --- | --- |
5024
- | `--message <text>` | Send a user message. Repeat it for a multi-turn local or `--url` run. `--prod` starts accept one message. |
5073
+ | `--message <text>` | Send a user message. Repeat it for a multi-turn local or `--url` run. A `--prod` run takes exactly one message. |
5025
5074
  | `--messages-file <path>` | Read a JSON array of strings. File messages run before repeated `--message` values. |
5026
- | `--session <id>` | Continue a session. With `--prod`, pass a hosted `ses_...` ID. |
5027
- | `--continuation-token <token>` | Continue the session selected by `--session` on a running server. `--prod` starts use `--session` instead. |
5075
+ | `--session <id>` | Continue a session. With `--prod`, pass a hosted `ses_...` ID from a session that `run --prod` or `session --prod` started; Slack, SCM, and custom-route sessions can't be continued this way. |
5076
+ | `--continuation-token <token>` | Continue the session selected by `--session` on a running server. `--prod` doesn't accept it. |
5028
5077
  | `--events <file>` | Write the raw NDJSON stream to this path. |
5029
5078
  | `--no-events` | Skip the NDJSON trace. |
5030
5079
  | `--text` | Print a compact trajectory instead of JSON. |
5031
5080
  | `--timeout-ms <n>` | Stop waiting after a positive number of milliseconds. There is no default timeout. |
5032
5081
  | `--no-stream` | Hide live tool and reply progress on stderr. |
5033
- | `--dry-run` | Mark a `--prod` turn as non-mutating. |
5034
- | `--as-of <instant>` | Freeze a `--prod` session's clock at a timezone-bearing ISO-8601 instant. |
5035
- | `--component <key>` | Select a hosted deployment's component instead of its default. |
5082
+ | `--dry-run` | Start a `--prod` session that runs read tools and stubs write tools. |
5083
+ | `--as-of <instant>` | Freeze a `--prod` session's clock at an ISO-8601 instant with a timezone, such as `2026-08-31T12:00:00Z`. |
5084
+ | `--component <key>` | Wake a named component of a `--prod` deployment instead of its default. A continued session must belong to that component. |
5036
5085
 
5037
5086
  For local and running-server targets, JSON output contains `ok`, `sessionId`,
5038
5087
  `continuationToken`, `trace`, `playgroundUrl`, `playgroundHint`, `visualize`,
5039
5088
  and `trajectory`. The `trace` value gives the saved path when event output is
5040
- enabled. With `--prod`, `run` prints a `deliveryId` when the deployment accepts
5041
- the turn and returns before the turn finishes. A fresh start has no
5042
- `sessionId` yet, even with `--dry-run`; a continuation includes it. `--prod`
5043
- starts ignore `--events`, `--no-events`, `--text`, `--timeout-ms`, and
5044
- `--no-stream`, and a successful start exits `0` before the turn outcome is
5045
- known. See [Verify a hosted turn](/docs/deployment.md#verify-a-hosted-turn).
5089
+ enabled.
5090
+
5091
+ With `--prod`, `run` returns as soon as the deployment accepts the turn and
5092
+ exits `0` before the turn outcome is known. It prints `deliveryId`,
5093
+ `workflowId`, and `sessionMode`, plus `dryRun` and `asOf` when set. A fresh
5094
+ start has no `sessionId` yet; a continuation echoes the `--session` value.
5095
+ `--events`, `--no-events`, `--text`, `--timeout-ms`, and `--no-stream` have no
5096
+ effect. See [Verify a hosted turn](/docs/deployment.md#verify-a-hosted-turn) for
5097
+ finding and following the new session.
5046
5098
 
5047
5099
  ### Call a tool {#call}
5048
5100
 
@@ -5088,9 +5140,9 @@ Text output shows the session ID, channel, mode, turn count, running status,
5088
5140
  and update time. `--json` prints `{ sessions }`, including continuation
5089
5141
  tokens.
5090
5142
 
5091
- Hosted deployments don't support `sessions`. Find a hosted session in the
5092
- deployment's **Sessions** list in the dashboard, then check it with
5093
- [`session <sessionId> --prod`](#session).
5143
+ Hosted deployments don't support `sessions`. Find a hosted session ID in the
5144
+ [`logs --prod`](#logs) headers or the deployment's **Sessions** list in the
5145
+ dashboard, then check it with [`session <sessionId> --prod`](#session).
5094
5146
 
5095
5147
  ### Inspect a session {#session}
5096
5148
 
@@ -5100,7 +5152,7 @@ bdk session <sessionId> [--url <baseUrl> | --prod]
5100
5152
  [--json | --text | --events] [--out <file.ndjson>]
5101
5153
 
5102
5154
  bdk session --prod [<sessionId>] --slug <slug> --message <text>
5103
- [--dry-run] [--as-of <instant>] [--component <key>]
5155
+ [--team <id>] [--dry-run] [--as-of <instant>] [--component <key>]
5104
5156
  ```
5105
5157
 
5106
5158
  | Option | Contract |
@@ -5110,28 +5162,33 @@ bdk session --prod [<sessionId>] --slug <slug> --message <text>
5110
5162
  | `--json` | Print the trajectory object. |
5111
5163
  | `--events` | Print `{ sessionId, events }` with the raw event list. |
5112
5164
  | `--out <file.ndjson>` | Write the raw NDJSON trace instead of printing it. |
5113
- | `--prod --message <text>` | Start a hosted session or continue the supplied hosted session ID. |
5165
+ | `--prod --message <text>` | Start a hosted session, or continue the supplied hosted session ID, with the same contract as [`run --prod`](#run). |
5114
5166
 
5115
- `--events` and `--json` are mutually exclusive. With `--prod`, the command
5116
- prints the session's runs and logs in text or JSON, and `--events` and `--out`
5117
- aren't available. While a hosted turn is running, text output also reports the
5118
- event count so far and prints `Turn running; runs may lag behind events.` Use
5119
- [`resume`](#resume) to continue a conversational session.
5167
+ `--events` and `--json` are mutually exclusive. Use [`resume`](#resume) to
5168
+ continue a conversational session on a local or running server.
5169
+
5170
+ With `--prod`, the command prints the session's hosted executions: one line
5171
+ per run with its status, duration, and time, followed by that run's log
5172
+ lines. `--json` prints `{ sessionId, executions, startLog, ... }`. `--events`
5173
+ and `--out` aren't available. While a turn is running, text output also
5174
+ reports the event count and latest event type and prints
5175
+ `Turn running; runs may lag behind events.` A run can show `running` with no
5176
+ logs until the turn ends, so a growing event count is the progress signal.
5120
5177
 
5121
5178
  ### Follow logs {#logs}
5122
5179
 
5123
5180
  ```text
5124
5181
  bdk logs [sessionId] [--url <baseUrl> | --prod]
5125
- [--session <sessionId>] [--slug <slug>] [--once] [--json]
5182
+ [--session <sessionId>] [--slug <slug>] [--team <id>] [--once] [--json]
5126
5183
  ```
5127
5184
 
5128
5185
  The command follows logs until Ctrl-C. `--once` prints the current buffer and
5129
5186
  exits; `--json` emits newline-delimited JSON events. With `--prod`, it follows
5130
- the output of the hosted deployment's most recent sessions and prints a
5131
- `==> <sessionId> (<channel>) <==` header each time the output switches
5132
- sessions. Pass a session ID, as an argument or with `--session`, to follow only
5133
- that session. Hosted log events carry `sessionId` and `line` rather than
5134
- `index` and `at`.
5187
+ the output of the hosted deployment's most recent sessions on every channel
5188
+ and prints a `==> <sessionId> (<channel>) <==` header each time the output
5189
+ switches sessions. Pass a session ID, as an argument or with `--session`, to
5190
+ follow only that session; a session ID requires `--prod`. Hosted log events
5191
+ carry `sessionId` and `line` rather than `index` and `at`.
5135
5192
 
5136
5193
  ### Report costs {#cost}
5137
5194
 
@@ -5155,8 +5212,8 @@ bdk playground [--url <baseUrl> | --prod] [--session <id>]
5155
5212
  The command prints the playground URL and opens it unless `--print` is set.
5156
5213
  `--session` opens a deep link. A running target with credentials that a
5157
5214
  browser can't send starts a loopback proxy and stays open until Ctrl-C.
5158
- `--session` links for a hosted deployment may not open yet; check that session
5159
- with [`session <sessionId> --prod`](#session) instead.
5215
+ With `--prod`, the URL opens the deployment's playground under **Deployed
5216
+ Agents** in the dashboard.
5160
5217
 
5161
5218
  ### Inspect a trajectory {#trajectory}
5162
5219
 
@@ -5386,7 +5443,7 @@ automatic warning.
5386
5443
  ```text
5387
5444
  bdk deploy [--dir <path>] [--slug <slug> | --all] [--team <id>]
5388
5445
  [--repo <https-url>] [--ref <git-ref>] [--path <agent-path>]
5389
- [--cursor-events-repo <owner/name>]...
5446
+ [--cursor-events-repo <repo>]...
5390
5447
  [--allow-domain <domain>]... [--no-wait] [--json]
5391
5448
  ```
5392
5449
 
@@ -5401,7 +5458,7 @@ service-account API key with agent access can deploy.
5401
5458
  | `--repo <https-url>` | Set the source repository. The CLI infers it from the current checkout when possible. HTTPS is required. |
5402
5459
  | `--ref <git-ref>` | Set the source Git ref. The CLI infers the current branch when possible. |
5403
5460
  | `--path <agent-path>` | Set the project path relative to the repository root. |
5404
- | `--cursor-events-repo <owner/name>` | Watch a repository's Cursor events. Repeat the flag for each repository; the repositories you pass replace the previous list. Without the flag, the deployment watches its GitHub source repository. |
5461
+ | `--cursor-events-repo <repo>` | Watch a repository's Cursor events. Write `owner/name` for GitHub and Origin, `gitlab.com/<group>/<project>` for GitLab (subgroups allowed), or `bitbucket.org/<workspace>/<repo>` for Bitbucket. Repeat the flag for each repository; the repositories you pass replace the previous list. Without the flag, the deployment watches its GitHub source repository. |
5405
5462
  | `--allow-domain <domain>` | Add an egress hostname. Repeat for multiple domains; values are combined with `hosting.egressDomains`. |
5406
5463
  | `--no-wait` | Return after the deployment request is accepted. |
5407
5464
  | `--json` | Print one object for one target or an array for multiple targets. |
@@ -5446,6 +5503,36 @@ The command waits for `stopped` by default. `--no-wait` returns after the
5446
5503
  request is accepted. `--cancel-runs` also requests cancellation of active
5447
5504
  runs and reminder wakes.
5448
5505
 
5506
+ ### Start a deployment {#start}
5507
+
5508
+ ```text
5509
+ bdk start <slug> [--team <id>] [--json]
5510
+ ```
5511
+
5512
+ `start` resumes a stopped deployment. It doesn't remove the deploy lock
5513
+ that [`kill`](#kill) sets.
5514
+
5515
+ ### Kill a deployment {#kill}
5516
+
5517
+ ```text
5518
+ bdk kill <slug> [--team <id>] [--json]
5519
+ ```
5520
+
5521
+ Use `kill` in an emergency. It locks deploys of the slug, stops the
5522
+ deployment, and requests cancellation of its active runs and reminder
5523
+ wakes. To bring the deployment back, run
5524
+ [`unlock-deploys`](#unlock-deploys) and then [`start`](#start).
5525
+
5526
+ ### Unlock deploys {#unlock-deploys}
5527
+
5528
+ ```text
5529
+ bdk unlock-deploys <slug> [--team <id>] [--json]
5530
+ ```
5531
+
5532
+ `unlock-deploys` removes the lock that `kill` sets, so `deploy`,
5533
+ `upgrade`, and `rollback` work for the slug again. It doesn't resume
5534
+ traffic; run `start` for that.
5535
+
5449
5536
  ### Cancel active runs {#cancel-runs}
5450
5537
 
5451
5538
  ```text
@@ -5476,6 +5563,17 @@ bdk upgrade <slug> [--release <id-or-version>]
5476
5563
  `--release` accepts a release ID or version. Omit it to select the newest
5477
5564
  ready release. `--json` prints `{ releaseId }`.
5478
5565
 
5566
+ ### Roll back a deployment {#rollback}
5567
+
5568
+ ```text
5569
+ bdk rollback <slug> [--release <id-or-version>]
5570
+ [--team <id>] [--json]
5571
+ ```
5572
+
5573
+ `rollback` moves the deployment to an earlier ready release without
5574
+ building a new one. Omit `--release` to select the release before the
5575
+ current one. `--json` prints `{ releaseId }`.
5576
+
5479
5577
  ### Delete a deployment {#delete}
5480
5578
 
5481
5579
  ```text
@@ -5524,6 +5622,24 @@ most 4096 bytes, and each deployment holds at most 32 secrets.
5524
5622
  `{ secretNames }` for `set`, `{ secrets }` for `list`, and `{ removed }` for
5525
5623
  `unset`. Changes are available to subsequent hosted work.
5526
5624
 
5625
+ ### Manage container images {#images}
5626
+
5627
+ ```text
5628
+ bdk images push <local-image> --name <name> [--team <id>] [--json]
5629
+ bdk images list [--team <id>] [--json]
5630
+ bdk images rm <name> [--team <id>] [--json]
5631
+ ```
5632
+
5633
+ A persistent agent can run inside a container image that your team pushes
5634
+ and names in `hosting.image`. `push` needs Docker on your machine. It
5635
+ checks the local image first: the image must be `linux/amd64` and have
5636
+ `bash`, `git`, `node` 22.13 or newer, and `npm` on `PATH`. The command
5637
+ then compresses the image and uploads it under `--name`.
5638
+
5639
+ `list` shows the team's images and how many the team can keep, and `rm`
5640
+ deletes one image. A deploy pins the image it uses, so after you push a
5641
+ new image under the same name, deploy again to pick it up.
5642
+
5527
5643
  ## MCP connections
5528
5644
 
5529
5645
  ### Connect an MCP client {#mcp}
@@ -5540,10 +5656,13 @@ bdk mcp install --url <baseUrl> [--bearer-token <token>]
5540
5656
  | `mcp` | Read newline-delimited JSON-RPC from stdin and proxy it to the selected agent's MCP endpoint. stdout is reserved for MCP messages. A target is required. |
5541
5657
  | `mcp install` | Add the selected agent to `~/.cursor/mcp.json`. `--name` sets the server name, `--print` previews the entry, and `--json` prints a machine-readable result. A `--url` entry with `--bearer-token` contains that token; handle printed and written copies as credentials. |
5542
5658
 
5659
+ Hosted deployments don't support `mcp` or `mcp install`; both report that the
5660
+ deployment doesn't support the command when you pass `--prod`.
5661
+
5543
5662
  ### Authorize MCP OAuth {#mcp-oauth}
5544
5663
 
5545
5664
  ```text
5546
- bdk mcp oauth <connection> [--dir <path>] [--store]
5665
+ bdk mcp oauth <connection> [--dir <path>]
5547
5666
  [--slug <slug>] [--team <id>]
5548
5667
  ```
5549
5668
 
@@ -5552,13 +5671,11 @@ bdk mcp oauth <connection> [--dir <path>] [--store]
5552
5671
 
5553
5672
  | Connection | Result |
5554
5673
  | --- | --- |
5555
- | `defineConnection({ url, oauth: true })` | Open a browser PKCE flow and save tokens in `mcp-auth.json` under the CLI config directory. `--store` also sets the matching deployment secrets. |
5556
- | `defineConnection({ cursorAccount: true })` | Authorize the hosted deployment's service account through Cursor. `--store` isn't needed. |
5674
+ | `defineConnection({ url, oauth: true })` | Open a browser PKCE flow and save tokens in `mcp-auth.json` under the CLI config directory. |
5675
+ | `defineConnection({ cursorAccount: true })` | Authorize the hosted deployment's service account through Cursor. |
5557
5676
 
5558
- Stored secret names are `MCP_OAUTH_<NAME>_ACCESS_TOKEN`,
5559
- `MCP_OAUTH_<NAME>_REFRESH_TOKEN`, and `MCP_OAUTH_<NAME>_CLIENT_ID`. Declare
5560
- them in `hosting.secretNames`. URL-connection tokens are bound to the resource
5561
- URL; authorize again after changing it.
5677
+ URL-connection tokens are bound to the resource URL; authorize again after
5678
+ changing it.
5562
5679
 
5563
5680
  See [Host MCP OAuth](/docs/guides/mcp-oauth.md) for the full setup flow.
5564
5681
 
@@ -5802,8 +5919,9 @@ empty value at connect time, which the server reports as an auth failure.
5802
5919
 
5803
5920
  For servers that speak OAuth, set `oauth: true` and authorize with the
5804
5921
  CLI or mid-run Connect. Tokens live in `mcp-auth.json` under the CLI
5805
- config directory. `--store` copies them onto the deployment as
5806
- `MCP_OAUTH_<NAME>_*` secrets.
5922
+ config directory of the machine that authorized them. A hosted agent
5923
+ reaches OAuth servers through a
5924
+ [Cursor account connection](#cursor-account-mcp-connection) instead.
5807
5925
 
5808
5926
  ```ts
5809
5927
  export default defineConnection({
@@ -5813,8 +5931,7 @@ export default defineConnection({
5813
5931
  ```
5814
5932
 
5815
5933
  ```text
5816
- bdk mcp oauth inventory # browser PKCE → local mcp-auth.json
5817
- bdk mcp oauth inventory --store # also upsert deployment secrets
5934
+ bdk mcp oauth inventory # browser PKCE → local mcp-auth.json
5818
5935
  ```
5819
5936
 
5820
5937
  Full walkthrough: [Host MCP OAuth](/docs/guides/mcp-oauth.md). Companion
@@ -6035,7 +6152,8 @@ connection.
6035
6152
 
6036
6153
  ## Related
6037
6154
 
6038
- - [Host MCP OAuth](/docs/guides/mcp-oauth.md): `mcp oauth`, Connect, `--store`
6155
+ - [Host MCP OAuth](/docs/guides/mcp-oauth.md): `mcp oauth`, Connect, and
6156
+ hosted agents
6039
6157
  - [Tools](/docs/reference/tools.md): authored tools that wrap MCP connections
6040
6158
  - [Webhooks](/docs/guides/webhooks.md): calling MCP connections from handlers
6041
6159
  - [Peer agents](/docs/guides/agent-to-agent.md): when a specialist is its
@@ -6130,8 +6248,7 @@ file-level metadata; case reporters add to the file's reporters.
6130
6248
  ## Send turns in a case
6131
6249
 
6132
6250
  `await t.send(message, options?)` runs one turn and waits until it
6133
- finishes, fails, or parks for approval. Several sends in one test share
6134
- the session.
6251
+ finishes or fails. Several sends in one test share the session.
6135
6252
 
6136
6253
  The returned turn exposes its assistant `message`, `sessionId`,
6137
6254
  `events`, ordered `toolCalls`, `ok`, and one-based `index`. Assertions
@@ -6157,8 +6274,7 @@ reports every violated contract.
6157
6274
 
6158
6275
  | Assertion | Checks |
6159
6276
  | --- | --- |
6160
- | `t.succeeded()` | Run finished without failure or an unanswered approval |
6161
- | `t.parked()` | Run stopped on an unanswered approval |
6277
+ | `t.succeeded()` | Run finished without failure |
6162
6278
  | `t.calledTool(name, matcher?)` | Matching tool request occurred |
6163
6279
  | `t.notCalledTool(name)` | No request for that tool occurred |
6164
6280
  | `t.loadedSkill(name)` | Agent opened a named skill |
@@ -6251,6 +6367,19 @@ call, with the nearest value winning.
6251
6367
  Treat agent output as untrusted input: wrap it with `fenceUntrusted` and
6252
6368
  include `EVAL_JUDGE_INJECTION_GUARD` in the judge prompt.
6253
6369
 
6370
+ ## Judge host
6371
+
6372
+ A judge grades by calling a Cursor model. It needs a Cursor credential
6373
+ (`bdk login`, `CURSOR_API_KEY`, or `CURSOR_SERVICE_ACCOUNT_KEY`) and a
6374
+ judge model. The grading session offers no tools and turns the local SDK
6375
+ sandbox off, including any per-user sandbox config on the machine, so the
6376
+ same case grades on macOS, a Linux cloud agent, and a Linux CI runner.
6377
+
6378
+ Without a credential, or when that credential belongs to a different
6379
+ backend than the SDK will call, the case is skipped and the suite
6380
+ continues. Without a judge model, the case fails and the assertion names
6381
+ where to set one.
6382
+
6254
6383
  ## Datasets and fixtures
6255
6384
 
6256
6385
  Load committed JSON, JSONL, or YAML relative to the project root:
@@ -6702,7 +6831,6 @@ All three consume the same stream, for different jobs:
6702
6831
  | Add context before the model runs | The channel's `send` message and `workspaceFiles`, `instructions.md`, skills, or `sandbox/workspace/` seed files |
6703
6832
  | Reply on Slack, comment on a PR, or post any other delivery | The channel's `events` map, or the Slack and GitHub packs |
6704
6833
  | Show PR progress (merge-box check, sticky banner) | `githubChannel({ progress: { commitStatus, banner } })`; see [GitHub agents](/docs/guides/github.md) |
6705
- | Block, approve, or rewrite a tool call | [`needsApproval`](/docs/reference/tools.md#gate-a-tool-on-human-approval) on the tool |
6706
6834
  | Act on the final assistant text, reject it for a same-turn repair, or fail a bad turn | `defineResult` |
6707
6835
  | Gate a change on behavior | [Evals](/docs/evals.md) |
6708
6836
 
@@ -6745,8 +6873,9 @@ chain, and session-owned resources return `403` to another principal.
6745
6873
  Unless a section says otherwise, the default auth policy is
6746
6874
  `localDevStrict()`. `--bearer-token` replaces it with bearer auth, and
6747
6875
  `--allow-anonymous` replaces it with anonymous access. Built-in JSON
6748
- routes use `{ ok: false, error: "<code>", message? }` for errors; MCP
6749
- uses JSON-RPC, and custom channel handlers define their own responses.
6876
+ routes use `{ ok: false, error: "<code>", message? }` for errors, and MCP
6877
+ uses JSON-RPC. Custom channel routes answer hosted callers with an empty
6878
+ `202`; see [Call custom channel routes](#call-custom-channel-routes).
6750
6879
 
6751
6880
  ## Host routes
6752
6881
 
@@ -6758,7 +6887,6 @@ exist only when the playground is enabled.
6758
6887
  | `GET /` | HTML index of mounted agents; no auth |
6759
6888
  | `GET /v1/agents` | JSON index of mounted agents; no auth |
6760
6889
  | `GET /docs`, `GET /docs/*` | Documentation site in either layout; no auth |
6761
- | `GET /v1/health` | Host liveness; no auth |
6762
6890
 
6763
6891
  `--no-playground` removes the two index routes. `--no-docs` removes the
6764
6892
  documentation site.
@@ -6833,15 +6961,6 @@ On loopback under `serve --dev`, the session list includes every
6833
6961
  principal so webhook and schedule sessions appear in the playground.
6834
6962
  The cost route returns `404` for an unknown session.
6835
6963
 
6836
- ## Resolve tool approvals
6837
-
6838
- | Route | Contract |
6839
- | --- | --- |
6840
- | `GET /v1/session/:sessionId/approvals` | List pending tool approvals |
6841
- | `POST /v1/session/:sessionId/approvals/:callId` | Resolve one with `{"decision":"approve"}` or `{"decision":"deny"}` |
6842
-
6843
- For the lifecycle, see [Gate a tool on human approval](/docs/reference/tools.md#gate-a-tool-on-human-approval).
6844
-
6845
6964
  ## Call a tool without a model turn
6846
6965
 
6847
6966
  `POST /v1/tools/:toolName` runs a server tool with no model turn.
@@ -6873,8 +6992,7 @@ These read-only routes describe the running agent.
6873
6992
  | --- | --- |
6874
6993
  | `GET /v1/info` | Return the discovered model, tools, skills, connections, subagents, channels, schedules, hooks, and diagnostics |
6875
6994
  | `GET /v1/tools` | Return live server tools and advertised MCP tools as `{ name, title?, source? }`; bind session-specific listings with `session` or `continuationToken` |
6876
- | `GET /v1/tools/:name` | Return one tool's description, execution mode, approval and effect rules, schemas, and source |
6877
- | `GET /v1/health` | Return per-agent liveness; no auth |
6995
+ | `GET /v1/tools/:name` | Return one tool's description, execution mode, effect rules, schemas, and source |
6878
6996
  | `GET /v1/logs?after=N` | Return recent server logs and the next polling cursor |
6879
6997
 
6880
6998
  An unknown tool name returns `404` with available names. If an MCP
@@ -6894,9 +7012,9 @@ The list follows the same ownership rules as `GET /v1/sessions`. See
6894
7012
  ## Call custom channel routes
6895
7013
 
6896
7014
  Authored routes mount under `/v1/channels/<id>` with their declared
6897
- methods and paths. The host validates their Zod body and query schemas
6898
- before calling the handler, returning `400` on failure. Each channel's
6899
- auth chain applies. See [Channels](/docs/reference/channels.md).
7015
+ methods and paths, and each channel's auth chain applies. A hosted
7016
+ caller receives `202 Accepted` with an empty body, never the handler's
7017
+ response. See [Route responses](/docs/reference/channels.md#route-responses).
6900
7018
 
6901
7019
  ## MCP endpoint
6902
7020
 
@@ -7049,9 +7167,8 @@ lists them all.
7049
7167
  | --- | --- |
7050
7168
  | Chat | Talk to the agent. Text and reasoning stream live, and tool calls appear inline with their arguments, output, and error state |
7051
7169
  | Slash commands | Custom channel routes without path parameters become composer commands; GitHub and Slack ingress routes are excluded. A `drive` route becomes `/drive <pr-url>`, with `/help` and autocomplete |
7052
- | Try | Invoke a custom channel route from the Agent tab. The modal remembers your last body per endpoint, copies curl, and opens a session when the route creates one |
7170
+ | Try | Invoke a custom channel route from the Agent tab. The modal remembers your last body per endpoint and copies curl. Find the session the route starts under Runs |
7053
7171
  | Runs | Browse the sessions you own and eval runs. Search by title or identifier; open sessions in Chat, Trace, or Raw and eval runs in Evals |
7054
- | Approvals | Parked `needsApproval` tool calls render Approve / Deny buttons |
7055
7172
  | Evals | List and run filesystem evals from the browser |
7056
7173
  | Agent | Inspect the discovered tools, skills, subagents, MCP connections, channels, and hooks |
7057
7174
  | Raw | Inspect the selected session's event stream |
@@ -7073,8 +7190,6 @@ and paste the token into the token field in the navbar.
7073
7190
 
7074
7191
  - [HTTP API](/docs/reference/http-api.md): the HTTP surface the playground uses
7075
7192
  - [Sessions and streaming](/docs/reference/sessions.md): the streams it renders
7076
- - [Gate a tool on human approval](/docs/reference/tools.md#gate-a-tool-on-human-approval):
7077
- the approval buttons in context
7078
7193
 
7079
7194
  ---
7080
7195
 
@@ -7315,6 +7430,7 @@ and `host` (shared services: `host.mcp`, `host.github`, `host.slack`,
7315
7430
 
7316
7431
  | Mode | What fires |
7317
7432
  | --- | --- |
7433
+ | Cursor-managed hosting | Cron cadence, from the schedules in the deployed release. See [Schedules on Cursor hosting](#schedules-on-cursor-hosting) |
7318
7434
  | Production `bdk serve` | Cron cadence. `--no-schedules` disables them. Run them in exactly one process per project |
7319
7435
  | `serve --dev` | Nothing automatic. Dispatch by hand through the same path production uses |
7320
7436
 
@@ -7326,6 +7442,27 @@ curl -X POST http://127.0.0.1:3000/<slug>/v1/dev/schedules/heartbeat
7326
7442
  The playground can dispatch schedules in dev mode too, and
7327
7443
  `handle.dispatchSchedule("heartbeat")` does it programmatically.
7328
7444
 
7445
+ ### Schedules on Cursor hosting
7446
+
7447
+ Each deploy registers the schedules in its release and replaces the
7448
+ previous set, so a schedule you delete from `bot/schedules/` stops after
7449
+ the next deploy. Hosted schedules need `@cursor/bdk` 0.2.14 or newer in
7450
+ the project. A deployment built with an earlier version has no hosted
7451
+ schedules until you upgrade the package and deploy again.
7452
+
7453
+ Every fire starts a new runtime. A Markdown schedule starts a task
7454
+ session there, and a `run` handler must finish in 26 minutes, including
7455
+ the work it passes to `receive` and `waitUntil`. Nothing in module memory
7456
+ carries over to the next fire, so keep state in `ctx.host.kv` or
7457
+ `ctx.host.files`. Each scheduled time starts at most one run, and a
7458
+ stopped deployment skips its fires.
7459
+
7460
+ A schedule's name is its path under `bot/schedules/` without the file
7461
+ extension. On Cursor hosting, a name has 1 to 100 letters, digits, `.`,
7462
+ `_`, `-`, or `/`, and starts with a letter or digit. A release holds at
7463
+ most 64 schedules, and `deploy` rejects a release that breaks either
7464
+ rule.
7465
+
7329
7466
  ## Reminders
7330
7467
 
7331
7468
  A reminder is created at runtime and bound to a channel continuation. A
@@ -7375,14 +7512,15 @@ await handle.createReminder({
7375
7512
  });
7376
7513
  ```
7377
7514
 
7378
- Use an anonymous `run` handler only for legacy projects that can re-arm
7379
- it after a restart. New projects should use a named handler.
7515
+ Architecture v2, the default, rejects an anonymous `run` handler and a
7516
+ function `until`, locally and on Cursor hosting. Use a prompt or a named
7517
+ handler.
7380
7518
 
7381
7519
  | Form | What it does | After a restart |
7382
7520
  | --- | --- | --- |
7383
7521
  | Prompt | Sends `prompt` into the session. `until` is the standing cancellation condition for the model | Stays armed |
7384
7522
  | Named handler | Runs a discovered handler with serializable `args`; it starts a model turn only if the handler calls `followup` | Stays armed |
7385
- | Anonymous `run` | Host handler returns `stop`, `skip`, or `delivered` per tick; it starts a model turn only if it calls `followup` | Must be re-armed |
7523
+ | Anonymous `run` | Architecture v1 only. Host handler returns `stop`, `skip`, or `delivered` per tick; it starts a model turn only if it calls `followup` | Must be re-armed |
7386
7524
 
7387
7525
  The same API is `host.reminders` on channel handlers, tools, and
7388
7526
  schedule runs. `builtinTools: { reminders: true }` adds
@@ -7453,7 +7591,7 @@ inspection are different jobs.
7453
7591
  | Identifier | Use it for |
7454
7592
  | --- | --- |
7455
7593
  | `continuationToken` | Continue a conversation through its channel |
7456
- | `sessionId` | Stream events, inspect state, resolve approvals, or run a session-bound tool call |
7594
+ | `sessionId` | Stream events, inspect state, or run a session-bound tool call |
7457
7595
 
7458
7596
  Channels decide what a continuation token looks like. Slack uses its
7459
7597
  thread identity. A PR channel can use a key such as `pr:owner/repo#1`.
@@ -7509,7 +7647,6 @@ within one session. The `at` field is an ISO-8601 timestamp.
7509
7647
  | Reasoning | `reasoning.appended`, `reasoning.completed` | Streamed reasoning blocks |
7510
7648
  | Reply | `message.appended`, `message.completed` | Text deltas and finalized assistant messages |
7511
7649
  | Tools | `actions.requested`, `actions.completed`, `action.result`, `action.tool_retry` | Tool names, validated arguments, outputs, and errors. `action.tool_retry` means a read is running again after a transient failure |
7512
- | Approvals | `action.approval_requested`, `action.approval_resolved` | A parked tool call and the human decision |
7513
7650
  | Subagents | `subagent.called`, `subagent.completed` | Delegated work |
7514
7651
  | Artifacts | `artifact.tagged` | A durable [artifact](/docs/reference/artifacts.md) was tagged for this session, by host code or `tag_artifact` |
7515
7652
 
@@ -7616,7 +7753,7 @@ description: Use when a pull request needs a structured approval checklist.
7616
7753
 
7617
7754
  1. Call `inspect_pr` and confirm required checks passed.
7618
7755
  2. Summarize the PR title, author, and remaining risks.
7619
- 3. Call `approve_pr` only after an explicit request; it requires approval.
7756
+ 3. Call `approve_pr` only after an explicit request.
7620
7757
  ```
7621
7758
 
7622
7759
  Use TypeScript when the content must be generated or include inline
@@ -7942,32 +8079,6 @@ use the same exposed names. See
7942
8079
  [MCP connections](/docs/reference/connections.md#advertise-tools) for the full
7943
8080
  contract.
7944
8081
 
7945
- ## Gate a tool on human approval
7946
-
7947
- A server tool can require a person to sign off before it runs. Set
7948
- `needsApproval` to `true`, or to a predicate over the validated input:
7949
-
7950
- ```ts
7951
- export default defineTool({
7952
- description: "Promote a verified build to an environment.",
7953
- needsApproval: true, // or: (input) => input.environment === "production"
7954
- inputSchema: z.object({
7955
- service: z.string(),
7956
- buildId: z.string(),
7957
- environment: z.string(),
7958
- }),
7959
- async execute({ service, buildId, environment }) {
7960
- return { promoted: true, service, buildId, environment };
7961
- },
7962
- });
7963
- ```
7964
-
7965
- The call parks, the turn stays running, and the stream emits
7966
- `action.approval_requested` until someone resolves it from the
7967
- playground, `POST /v1/session/:id/approvals/:callId`, or Slack
7968
- Approve/Deny cards. Approvals exist for server tools on the local
7969
- runtime only, and parked calls don't survive a host restart.
7970
-
7971
8082
  ## Call a tool without a model turn
7972
8083
 
7973
8084
  Server tools can be called deterministically. You pick the tool and the
@@ -8049,8 +8160,8 @@ spoofed payload can't steer it.
8049
8160
  Test tools with `call` before blaming prompts. If the tool's output is
8050
8161
  wrong, no instruction change fixes it.
8051
8162
 
8052
- Gate side effects with `needsApproval`. Declare each tool's `effect` so
8053
- dry-run sessions can execute reads and stub writes.
8163
+ Declare each tool's `effect` so dry-run sessions can execute reads and
8164
+ stub writes.
8054
8165
 
8055
8166
  ## Related
8056
8167
 
@@ -8211,7 +8322,7 @@ checked later, and an active turn can be interrupted when the task
8211
8322
  changes.
8212
8323
 
8213
8324
  See [Grok Bot agents](/docs/guides/grokbot-agents.md) for the extension's
8214
- conversation and approval boundaries.
8325
+ conversation boundaries.
8215
8326
 
8216
8327
  ## What to edit
8217
8328
 
@@ -8634,10 +8745,17 @@ Match the visible symptom below.
8634
8745
  | The deployment never becomes running | Run `bdk deployment <slug>`, then act on the reported build or startup error. |
8635
8746
  | A secret or egress change has no effect | Confirm the name with `secrets list`, verify the `hosting` block exists on the pushed ref, and follow the CLI or dashboard prompt to redeploy. |
8636
8747
  | Cursor events stopped after redeploy | Each redeploy replaces the watched repositories. Pass every `--cursor-events-repo` value again; without the flag, the deployment watches only its GitHub source repository. |
8637
- | `run --prod` prints a `deliveryId` but no `sessionId` | The deployment accepted the turn and is still starting it, which is expected with or without `--dry-run`. Find the session in the deployment's **Sessions** list in the dashboard, then follow [Verify a hosted turn](/docs/deployment.md#verify-a-hosted-turn). |
8638
- | A high-effort turn runs for several minutes while runs look empty | Turns can take about eight minutes. Rerun `bdk session <sessionId> --prod --slug <slug>`; a growing event count means the turn is still working. Escalate only after about two to three minutes with no new events. |
8639
- | A dashboard link to a single session returns 404 | Check the session with `bdk session <sessionId> --prod --slug <slug>`. |
8748
+ | `run --prod` prints a `deliveryId` but no `sessionId` | Expected, with or without `--dry-run`: the session is created when the turn starts. Find it with `bdk logs --prod --once --slug <slug>`, then follow [Verify a hosted turn](/docs/deployment.md#verify-a-hosted-turn). |
8749
+ | `session <sessionId> --prod` shows a `running` run with no logs | Runs lag behind events, and a high-effort turn can take several minutes. Rerun the command; a growing event count means the turn is still working. |
8750
+ | A dashboard link to a single session doesn't open | Check the session with `bdk session <sessionId> --prod --slug <slug>`. |
8751
+ | `chat`, `call`, `sessions`, `cost`, or `mcp` with `--prod` says the command is not supported | Hosted deployments accept `--prod` only on `run`, `session`, `logs`, and `playground`. See [Verify a hosted turn](/docs/deployment.md#verify-a-hosted-turn). |
8752
+ | `run --prod --session <sessionId>` reports the session belongs to another channel | `--session` continues only sessions that `run --prod` or `session --prod` started. Reach Slack, SCM, and custom-route sessions through their own channel. |
8753
+ | A custom route returns `202` with no body | Expected on managed hosting. The handler runs after the response, so deliver results from the channel. See [Route responses](/docs/reference/channels.md#route-responses). |
8640
8754
  | External HTTP rejects the alias token | Update the caller with the current token. If the token is lost or exposed, run `bdk rotate-token <slug>` and replace it everywhere. |
8755
+ | `deploy` says deployments are not available under legacy privacy mode | The team uses Privacy Mode (Legacy), which does not let Cursor store code. Managed hosting is not available with this setting. |
8756
+ | `deploy` says persistent deployments are limited to 1 per team | Another deployment of the team already sets `persistent: true`. Remove the setting from one agent, or delete that deployment. |
8757
+ | A schedule does not fire on the hosted deployment | Make sure the deployment is running and its release has the schedule. Deploy again with `@cursor/bdk` 0.2.14 or newer. |
8758
+ | A request to a custom route gets `429` | The deployment received more requests than its limit. Wait for the time in `Retry-After`, then send the request again. |
8641
8759
 
8642
8760
  See [Deployment](/docs/deployment.md) for source, credential, and
8643
8761
  redeployment boundaries.
@@ -8661,7 +8779,6 @@ direct webhooks.
8661
8779
  | Logs say `channel idle ... missing credentials` | Run `bdk slack create --dir <agent>`, then check the generated prefix with `bdk slack doctor`. Use `slack init --manual` only for an app you own. |
8662
8780
  | `slack create` is waiting for workspace approval | Keep the CLI running, open the **Request approval** link it prints, and select **Retry** in the dashboard's **Add Slack** wizard after an admin approves. See [Slack](/docs/guides/slack.md#connect). |
8663
8781
  | The bot ignores ordinary channel posts | Configure `engagement.channelPosts`, create the app with `--channel-posts`, and invite it to every allowed channel. |
8664
- | Approval buttons do nothing | Set `toolApprovals: true`, then recreate the app if its interactivity is not enabled. |
8665
8782
 
8666
8783
  See the [Slack guide](/docs/guides/slack.md) for app setup and engagement
8667
8784
  choices.
@@ -8671,17 +8788,16 @@ choices.
8671
8788
  | What you see | What to do |
8672
8789
  | --- | --- |
8673
8790
  | `must be defineConnection({ url, oauth: true })` | Add `oauth: true` to the named URL connection or correct the connection filename passed to `mcp oauth`. |
8674
- | Local auth works but hosted calls return unauthorized | Complete Connect for the running process, or run `mcp oauth <name> --store` and redeploy for future replacements. |
8791
+ | Local auth works but hosted calls return unauthorized | Locally stored OAuth tokens don't reach a deployment. Use a `cursorAccount: true` connection and connect the server from **Deployed Agents** in the dashboard. See [Host MCP OAuth](/docs/guides/mcp-oauth.md#use-an-oauth-server-from-a-hosted-agent). |
8675
8792
  | The model invents `mcp_auth` instead of calling the server | Set `advertiseTools: true` for named local tools, or expose a host-side wrapper through `ctx.host.mcp`. |
8676
8793
 
8677
8794
  See [Host MCP OAuth](/docs/guides/mcp-oauth.md) for the credential lifecycle.
8678
8795
 
8679
- ## Schedules, reminders, or approvals stall
8796
+ ## Schedules or reminders stall
8680
8797
 
8681
8798
  | What you see | What to do |
8682
8799
  | --- | --- |
8683
8800
  | A schedule or reminder never fires under `--dev` | Trigger it through the matching `/v1/dev/schedules/<id>` or `/v1/dev/reminders/<id>` route; development mode does not auto-fire. |
8684
- | A pending approval disappears after restart | Parked approvals do not survive restart. Run the turn again. |
8685
8801
  | A reminder is disarmed with `handler_lost_on_restart` | Recreate handler-form reminders after restart, or use a prompt-form reminder. |
8686
8802
  | The same schedule fires on several self-hosted processes | Enable schedules on one serving process per project and pass `--no-schedules` to the others. |
8687
8803