@cursor/july 0.1.92 → 0.1.93

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 (324) hide show
  1. package/README.md +117 -162
  2. package/dist/channels/deployments/deployments-channel.d.ts +7 -0
  3. package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
  4. package/dist/channels/deployments/deployments-channel.js +26 -2
  5. package/dist/channels/deployments/types.d.ts +8 -0
  6. package/dist/channels/deployments/types.d.ts.map +1 -1
  7. package/dist/channels/github/github-channel.d.ts +3 -0
  8. package/dist/channels/github/github-channel.d.ts.map +1 -1
  9. package/dist/channels/github/github-channel.js +28 -56
  10. package/dist/continuation.d.ts +1 -1
  11. package/dist/continuation.js +1 -1
  12. package/dist/docs/404.html +2 -2
  13. package/dist/docs/ab.html +8 -8
  14. package/dist/docs/ab.md +7 -13
  15. package/dist/docs/assets/{ab.md.CVzWxLoB.js → ab.md.DJo5r4R-.js} +4 -4
  16. package/dist/docs/assets/{ab.md.CVzWxLoB.lean.js → ab.md.DJo5r4R-.lean.js} +1 -1
  17. package/dist/docs/assets/{app.Bci6CM9E.js → app.CjWU-x0z.js} +1 -1
  18. package/dist/docs/assets/building-with-agents.md.DI4mEzlt.js +13 -0
  19. package/dist/docs/assets/{building-with-agents.md.DH8A_cHA.lean.js → building-with-agents.md.DI4mEzlt.lean.js} +1 -1
  20. package/dist/docs/assets/chunks/@localSearchIndexroot.ChpIC3Zy.js +1 -0
  21. package/dist/docs/assets/chunks/{VPLocalSearchBox.BCPT6xA-.js → VPLocalSearchBox.Cxy8ySFQ.js} +1 -1
  22. package/dist/docs/assets/chunks/{theme.BEA8BF3c.js → theme.Dvq1Bktu.js} +2 -2
  23. package/dist/docs/assets/concepts.md.F6AiPorA.js +1 -0
  24. package/dist/docs/assets/{concepts.md.CRfU3bVg.lean.js → concepts.md.F6AiPorA.lean.js} +1 -1
  25. package/dist/docs/assets/{deployment.md.DX_hc3ze.js → deployment.md.DoLFAzfm.js} +6 -6
  26. package/dist/docs/assets/{evals.md.a0SMN6r9.js → evals.md.lfJoEVc8.js} +6 -6
  27. package/dist/docs/assets/{evals.md.a0SMN6r9.lean.js → evals.md.lfJoEVc8.lean.js} +1 -1
  28. package/dist/docs/assets/{example-agents_approval-buddy.md.DNL83puR.js → example-agents_approval-buddy.md.DmezILPg.js} +1 -1
  29. package/dist/docs/assets/{example-agents_benny.md.C40vHRLc.js → example-agents_benny.md.B0kwY7D_.js} +2 -4
  30. package/dist/docs/assets/{example-agents_benny.md.C40vHRLc.lean.js → example-agents_benny.md.B0kwY7D_.lean.js} +1 -1
  31. package/dist/docs/assets/{example-agents_codebase-wiki.md.Dftj_tPp.js → example-agents_codebase-wiki.md.BBNw9Ekr.js} +3 -3
  32. package/dist/docs/assets/{example-agents_codebase-wiki.md.Dftj_tPp.lean.js → example-agents_codebase-wiki.md.BBNw9Ekr.lean.js} +1 -1
  33. package/dist/docs/assets/{example-agents_concierge.md.MrKpQndp.js → example-agents_concierge.md.BzB2b20R.js} +2 -3
  34. package/dist/docs/assets/example-agents_index.md.ChBp0AX6.js +2 -0
  35. package/dist/docs/assets/example-agents_index.md.ChBp0AX6.lean.js +1 -0
  36. package/dist/docs/assets/{example-agents_knowledge-base.md.DqKqHQ9u.js → example-agents_knowledge-base.md.CrA85ig-.js} +1 -1
  37. package/dist/docs/assets/{example-agents_security-reviewer.md.Bai6D0Ee.js → example-agents_security-reviewer.md.74pPpWYj.js} +1 -1
  38. package/dist/docs/assets/{example-agents_weather-agent.md.lVEAbWFf.js → example-agents_weather-agent.md.CaGpmw3Y.js} +2 -2
  39. package/dist/docs/assets/{guides_agent-to-agent.md.BCeVdJRJ.js → guides_agent-to-agent.md.B3JIaAqz.js} +1 -1
  40. package/dist/docs/assets/{guides_cloud-runtime.md.BSMLIBHr.js → guides_cloud-runtime.md.BnvjPiia.js} +2 -2
  41. package/dist/docs/assets/{guides_cloud-runtime.md.BSMLIBHr.lean.js → guides_cloud-runtime.md.BnvjPiia.lean.js} +1 -1
  42. package/dist/docs/assets/{guides_convert-automation.md.D06eIzea.js → guides_convert-automation.md.Bboisykk.js} +1 -1
  43. package/dist/docs/assets/{guides_github.md.Cdt1s2QC.js → guides_github.md.DqJhuaN1.js} +5 -5
  44. package/dist/docs/assets/{guides_github.md.Cdt1s2QC.lean.js → guides_github.md.DqJhuaN1.lean.js} +1 -1
  45. package/dist/docs/assets/{guides_mcp-oauth.md.Du0f7pGU.js → guides_mcp-oauth.md.CJvrXtkN.js} +2 -2
  46. package/dist/docs/assets/{guides_slack.md.DiUmk_Oi.js → guides_slack.md.mqeNKs84.js} +2 -2
  47. package/dist/docs/assets/{guides_webhooks.md.BpnIdO0i.js → guides_webhooks.md.DKdA43Qm.js} +2 -2
  48. package/dist/docs/assets/{hillclimbing.md.ywF3yDAd.js → hillclimbing.md.DhESf3OO.js} +1 -1
  49. package/dist/docs/assets/{index.md.BAaMXLFd.js → index.md.B-lVR4wT.js} +3 -3
  50. package/dist/docs/assets/{index.md.BAaMXLFd.lean.js → index.md.B-lVR4wT.lean.js} +1 -1
  51. package/dist/docs/assets/{quickstart.md.DsrarzEg.js → quickstart.md.BrmfrrIr.js} +1 -1
  52. package/dist/docs/assets/{reference_agent-config.md.Bqylgw50.js → reference_agent-config.md.Cp_x38Nl.js} +3 -3
  53. package/dist/docs/assets/{reference_channels.md.DQZjCnyh.js → reference_channels.md.Cd2f2iyV.js} +2 -2
  54. package/dist/docs/assets/{reference_channels.md.DQZjCnyh.lean.js → reference_channels.md.Cd2f2iyV.lean.js} +1 -1
  55. package/dist/docs/assets/{reference_cli.md.B7GkAJRC.js → reference_cli.md.D9KESDsD.js} +10 -11
  56. package/dist/docs/assets/{reference_cli.md.B7GkAJRC.lean.js → reference_cli.md.D9KESDsD.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_connections.md.DYidrb-j.js → reference_connections.md.DB6SsN6U.js} +3 -3
  58. package/dist/docs/assets/reference_hooks.md.BxN87gCw.js +14 -0
  59. package/dist/docs/assets/{reference_hooks.md.B9FSgdDe.lean.js → reference_hooks.md.BxN87gCw.lean.js} +1 -1
  60. package/dist/docs/assets/reference_http-api.md.C68BERYr.js +11 -0
  61. package/dist/docs/assets/reference_http-api.md.C68BERYr.lean.js +1 -0
  62. package/dist/docs/assets/{reference_instructions.md.DhNCOl7r.js → reference_instructions.md.CR7XSsGk.js} +3 -3
  63. package/dist/docs/assets/{reference_instructions.md.DhNCOl7r.lean.js → reference_instructions.md.CR7XSsGk.lean.js} +1 -1
  64. package/dist/docs/assets/reference_playground.md.DnX5nL-B.js +1 -0
  65. package/dist/docs/assets/reference_playground.md.DnX5nL-B.lean.js +1 -0
  66. package/dist/docs/assets/{reference_project-layout.md.CwkSbEWT.js → reference_project-layout.md.WN9nwJht.js} +2 -2
  67. package/dist/docs/assets/{reference_prompt.md.DZUMtLPD.js → reference_prompt.md.DnaD5dNK.js} +1 -1
  68. package/dist/docs/assets/{reference_schedules.md.DNipebiG.js → reference_schedules.md.DI_JrHgq.js} +1 -1
  69. package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +1 -0
  70. package/dist/docs/assets/{reference_sessions.md.tUFzz98S.lean.js → reference_sessions.md.D0mIh4KK.lean.js} +1 -1
  71. package/dist/docs/assets/{reference_skills.md.B5ZEuHfG.js → reference_skills.md.BFW9retM.js} +1 -1
  72. package/dist/docs/assets/{reference_tools.md.wpaJtHn6.js → reference_tools.md.DuKvkYWG.js} +4 -4
  73. package/dist/docs/assets/{reference_tools.md.wpaJtHn6.lean.js → reference_tools.md.DuKvkYWG.lean.js} +1 -1
  74. package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +1 -0
  75. package/dist/docs/assets/{scaffolding-agents.md.CRDDUtYJ.lean.js → scaffolding-agents.md.D7UUkWw0.lean.js} +1 -1
  76. package/dist/docs/assets/{storage.md.JbjlHWZ6.js → storage.md.BOHeqk2M.js} +5 -5
  77. package/dist/docs/assets/{storage.md.JbjlHWZ6.lean.js → storage.md.BOHeqk2M.lean.js} +1 -1
  78. package/dist/docs/assets/{templates_agentic-owners.md.DSJSIpWU.js → templates_agentic-owners.md.DqtPdm6f.js} +2 -2
  79. package/dist/docs/assets/{templates_pr-autofixer.md.1HAR3RXE.js → templates_pr-autofixer.md.R4K_qytS.js} +2 -2
  80. package/dist/docs/assets/{templates_pr-autofixer.md.1HAR3RXE.lean.js → templates_pr-autofixer.md.R4K_qytS.lean.js} +1 -1
  81. package/dist/docs/assets/troubleshooting.md.vCWwvqcJ.js +1 -0
  82. package/dist/docs/assets/{troubleshooting.md.DYECCZiJ.lean.js → troubleshooting.md.vCWwvqcJ.lean.js} +1 -1
  83. package/dist/docs/building-with-agents.html +7 -7
  84. package/dist/docs/building-with-agents.md +5 -11
  85. package/dist/docs/concepts.html +5 -8
  86. package/dist/docs/concepts.md +12 -17
  87. package/dist/docs/deployment.html +11 -11
  88. package/dist/docs/deployment.md +8 -10
  89. package/dist/docs/evals.html +10 -10
  90. package/dist/docs/evals.md +16 -37
  91. package/dist/docs/example-agents/approval-buddy.html +5 -5
  92. package/dist/docs/example-agents/approval-buddy.md +1 -1
  93. package/dist/docs/example-agents/benny.html +5 -7
  94. package/dist/docs/example-agents/benny.md +4 -13
  95. package/dist/docs/example-agents/bugbot.html +4 -4
  96. package/dist/docs/example-agents/codebase-wiki.html +6 -6
  97. package/dist/docs/example-agents/codebase-wiki.md +5 -8
  98. package/dist/docs/example-agents/codeowners-review.html +4 -4
  99. package/dist/docs/example-agents/concierge.html +7 -8
  100. package/dist/docs/example-agents/concierge.md +2 -3
  101. package/dist/docs/example-agents/index.html +6 -6
  102. package/dist/docs/example-agents/index.md +5 -8
  103. package/dist/docs/example-agents/knowledge-base.html +6 -6
  104. package/dist/docs/example-agents/knowledge-base.md +2 -2
  105. package/dist/docs/example-agents/oncall.html +4 -4
  106. package/dist/docs/example-agents/security-reviewer.html +7 -7
  107. package/dist/docs/example-agents/security-reviewer.md +5 -5
  108. package/dist/docs/example-agents/slack-agent.html +4 -4
  109. package/dist/docs/example-agents/weather-agent.html +7 -7
  110. package/dist/docs/example-agents/weather-agent.md +4 -3
  111. package/dist/docs/guides/agent-to-agent.html +5 -5
  112. package/dist/docs/guides/agent-to-agent.md +1 -1
  113. package/dist/docs/guides/cloud-runtime.html +6 -6
  114. package/dist/docs/guides/cloud-runtime.md +8 -25
  115. package/dist/docs/guides/convert-automation.html +6 -6
  116. package/dist/docs/guides/convert-automation.md +3 -3
  117. package/dist/docs/guides/github.html +9 -9
  118. package/dist/docs/guides/github.md +11 -23
  119. package/dist/docs/guides/human-in-the-loop.html +4 -4
  120. package/dist/docs/guides/mcp-oauth.html +6 -6
  121. package/dist/docs/guides/mcp-oauth.md +4 -4
  122. package/dist/docs/guides/opentelemetry.html +4 -4
  123. package/dist/docs/guides/slack.html +7 -7
  124. package/dist/docs/guides/slack.md +4 -4
  125. package/dist/docs/guides/webhooks.html +6 -6
  126. package/dist/docs/guides/webhooks.md +3 -3
  127. package/dist/docs/hashmap.json +1 -1
  128. package/dist/docs/hillclimbing.html +6 -6
  129. package/dist/docs/hillclimbing.md +1 -1
  130. package/dist/docs/index.html +6 -6
  131. package/dist/docs/index.md +2 -10
  132. package/dist/docs/llms-full.txt +300 -850
  133. package/dist/docs/llms.txt +2 -3
  134. package/dist/docs/quickstart.html +5 -5
  135. package/dist/docs/quickstart.md +1 -1
  136. package/dist/docs/reference/agent-config.html +8 -8
  137. package/dist/docs/reference/agent-config.md +10 -15
  138. package/dist/docs/reference/artifacts.html +4 -4
  139. package/dist/docs/reference/channels.html +6 -6
  140. package/dist/docs/reference/channels.md +20 -31
  141. package/dist/docs/reference/cli.html +14 -15
  142. package/dist/docs/reference/cli.md +27 -37
  143. package/dist/docs/reference/connections.html +8 -8
  144. package/dist/docs/reference/connections.md +9 -14
  145. package/dist/docs/reference/hooks.html +6 -6
  146. package/dist/docs/reference/hooks.md +10 -14
  147. package/dist/docs/reference/http-api.html +7 -7
  148. package/dist/docs/reference/http-api.md +17 -37
  149. package/dist/docs/reference/instructions.html +6 -6
  150. package/dist/docs/reference/instructions.md +1 -1
  151. package/dist/docs/reference/playground.html +5 -5
  152. package/dist/docs/reference/playground.md +14 -19
  153. package/dist/docs/reference/project-layout.html +7 -7
  154. package/dist/docs/reference/project-layout.md +2 -2
  155. package/dist/docs/reference/prompt.html +6 -6
  156. package/dist/docs/reference/prompt.md +1 -1
  157. package/dist/docs/reference/schedules.html +6 -6
  158. package/dist/docs/reference/schedules.md +1 -2
  159. package/dist/docs/reference/sessions.html +5 -12
  160. package/dist/docs/reference/sessions.md +8 -19
  161. package/dist/docs/reference/skills.html +6 -6
  162. package/dist/docs/reference/skills.md +3 -3
  163. package/dist/docs/reference/subagents.html +4 -4
  164. package/dist/docs/reference/tools.html +8 -8
  165. package/dist/docs/reference/tools.md +12 -17
  166. package/dist/docs/scaffolding-agents.html +5 -5
  167. package/dist/docs/scaffolding-agents.md +4 -5
  168. package/dist/docs/storage.html +9 -9
  169. package/dist/docs/storage.md +37 -80
  170. package/dist/docs/templates/agentic-owners.html +7 -7
  171. package/dist/docs/templates/agentic-owners.md +2 -2
  172. package/dist/docs/templates/demo.html +4 -4
  173. package/dist/docs/templates/pr-autofixer.html +6 -6
  174. package/dist/docs/templates/pr-autofixer.md +3 -6
  175. package/dist/docs/templates/security-reviewer.html +4 -4
  176. package/dist/docs/templates/triage.html +4 -4
  177. package/dist/docs/troubleshooting.html +5 -5
  178. package/dist/docs/troubleshooting.md +6 -6
  179. package/dist/internal/authored-alias-hooks.d.ts +14 -11
  180. package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
  181. package/dist/internal/authored-alias-hooks.js +14 -11
  182. package/dist/internal/authored-loaders.d.ts +7 -6
  183. package/dist/internal/authored-loaders.d.ts.map +1 -1
  184. package/dist/internal/authored-loaders.js +14 -10
  185. package/dist/internal/cli-deploy.d.ts +1 -1
  186. package/dist/internal/cli-deploy.js +5 -5
  187. package/dist/internal/continuation-channel.d.ts +6 -3
  188. package/dist/internal/continuation-channel.d.ts.map +1 -1
  189. package/dist/internal/continuation-channel.js +44 -40
  190. package/dist/internal/continuation-identity.d.ts +17 -16
  191. package/dist/internal/continuation-identity.d.ts.map +1 -1
  192. package/dist/internal/continuation-identity.js +109 -36
  193. package/dist/internal/deploy-manifest.d.ts +2 -2
  194. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  195. package/dist/internal/deploy-manifest.js +4 -9
  196. package/dist/internal/discovery.d.ts.map +1 -1
  197. package/dist/internal/discovery.js +3 -0
  198. package/dist/internal/distribution.d.ts +4 -3
  199. package/dist/internal/distribution.d.ts.map +1 -1
  200. package/dist/internal/distribution.js +4 -3
  201. package/dist/internal/hosted-delivery-protocol.d.ts +38 -0
  202. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -0
  203. package/dist/internal/hosted-delivery-protocol.js +70 -0
  204. package/dist/internal/hosted-delivery.d.ts +35 -0
  205. package/dist/internal/hosted-delivery.d.ts.map +1 -0
  206. package/dist/internal/hosted-delivery.js +226 -0
  207. package/dist/internal/http-channel.d.ts.map +1 -1
  208. package/dist/internal/http-channel.js +1 -1
  209. package/dist/internal/review-comments.d.ts +186 -63
  210. package/dist/internal/review-comments.d.ts.map +1 -1
  211. package/dist/internal/review-comments.js +350 -168
  212. package/dist/internal/server.d.ts.map +1 -1
  213. package/dist/internal/server.js +21 -3
  214. package/dist/internal/session-engine.d.ts +5 -0
  215. package/dist/internal/session-engine.d.ts.map +1 -1
  216. package/dist/internal/session-engine.js +13 -3
  217. package/dist/internal/shallow-clone.d.ts +8 -2
  218. package/dist/internal/shallow-clone.d.ts.map +1 -1
  219. package/dist/internal/shallow-clone.js +17 -10
  220. package/dist/playground/assets/{index-DDvyC2z6.js → index-D9MFzhNE.js} +1 -1
  221. package/dist/playground/index.html +1 -1
  222. package/dist/types.d.ts +9 -17
  223. package/dist/types.d.ts.map +1 -1
  224. package/docs/README.md +2 -10
  225. package/docs/ab.md +7 -13
  226. package/docs/building-with-agents.md +5 -11
  227. package/docs/concepts.md +12 -17
  228. package/docs/deployment.md +8 -10
  229. package/docs/evals.md +16 -37
  230. package/docs/example-agents/approval-buddy.md +1 -1
  231. package/docs/example-agents/benny.md +4 -13
  232. package/docs/example-agents/codebase-wiki.md +5 -8
  233. package/docs/example-agents/concierge.md +2 -3
  234. package/docs/example-agents/index.md +6 -9
  235. package/docs/example-agents/knowledge-base.md +2 -2
  236. package/docs/example-agents/security-reviewer.md +5 -5
  237. package/docs/example-agents/weather-agent.md +4 -3
  238. package/docs/guides/agent-to-agent.md +1 -1
  239. package/docs/guides/cloud-runtime.md +8 -25
  240. package/docs/guides/convert-automation.md +3 -3
  241. package/docs/guides/github.md +11 -23
  242. package/docs/guides/mcp-oauth.md +4 -4
  243. package/docs/guides/slack.md +4 -4
  244. package/docs/guides/webhooks.md +3 -3
  245. package/docs/hillclimbing.md +1 -1
  246. package/docs/quickstart.md +1 -1
  247. package/docs/reference/agent-config.md +10 -15
  248. package/docs/reference/channels.md +20 -31
  249. package/docs/reference/cli.md +27 -37
  250. package/docs/reference/connections.md +9 -14
  251. package/docs/reference/hooks.md +10 -14
  252. package/docs/reference/http-api.md +18 -38
  253. package/docs/reference/instructions.md +1 -1
  254. package/docs/reference/playground.md +14 -19
  255. package/docs/reference/project-layout.md +2 -2
  256. package/docs/reference/prompt.md +1 -1
  257. package/docs/reference/schedules.md +1 -2
  258. package/docs/reference/sessions.md +8 -19
  259. package/docs/reference/skills.md +3 -3
  260. package/docs/reference/tools.md +12 -17
  261. package/docs/scaffolding-agents.md +4 -5
  262. package/docs/storage.md +37 -80
  263. package/docs/templates/agentic-owners.md +2 -2
  264. package/docs/templates/pr-autofixer.md +3 -6
  265. package/docs/troubleshooting.md +6 -6
  266. package/package.json +8 -1
  267. package/src/channels/deployments/deployments-channel.ts +32 -2
  268. package/src/channels/deployments/types.ts +8 -0
  269. package/src/channels/github/github-channel.ts +71 -21
  270. package/src/continuation.ts +1 -1
  271. package/src/internal/authored-alias-hooks.ts +14 -11
  272. package/src/internal/authored-loaders.ts +14 -10
  273. package/src/internal/cli-deploy.ts +5 -5
  274. package/src/internal/continuation-channel.ts +62 -45
  275. package/src/internal/continuation-identity.ts +123 -38
  276. package/src/internal/deploy-manifest.ts +5 -9
  277. package/src/internal/discovery.ts +3 -0
  278. package/src/internal/distribution.ts +4 -3
  279. package/src/internal/hosted-delivery-protocol.ts +114 -0
  280. package/src/internal/hosted-delivery.ts +327 -0
  281. package/src/internal/http-channel.ts +0 -2
  282. package/src/internal/review-comments.ts +542 -229
  283. package/src/internal/server.ts +29 -2
  284. package/src/internal/session-engine.ts +25 -1
  285. package/src/internal/shallow-clone.ts +30 -16
  286. package/src/types.ts +9 -17
  287. package/dist/docs/assets/building-with-agents.md.DH8A_cHA.js +0 -13
  288. package/dist/docs/assets/chunks/@localSearchIndexroot.Dv-Q0XtU.js +0 -1
  289. package/dist/docs/assets/concepts.md.CRfU3bVg.js +0 -4
  290. package/dist/docs/assets/example-agents_fsd.md.ZWHWWZPE.js +0 -15
  291. package/dist/docs/assets/example-agents_fsd.md.ZWHWWZPE.lean.js +0 -1
  292. package/dist/docs/assets/example-agents_index.md.QZ8mhr6n.js +0 -2
  293. package/dist/docs/assets/example-agents_index.md.QZ8mhr6n.lean.js +0 -1
  294. package/dist/docs/assets/reference_hooks.md.B9FSgdDe.js +0 -14
  295. package/dist/docs/assets/reference_http-api.md.CSHVobzG.js +0 -11
  296. package/dist/docs/assets/reference_http-api.md.CSHVobzG.lean.js +0 -1
  297. package/dist/docs/assets/reference_playground.md.Dfb92yQf.js +0 -1
  298. package/dist/docs/assets/reference_playground.md.Dfb92yQf.lean.js +0 -1
  299. package/dist/docs/assets/reference_sessions.md.tUFzz98S.js +0 -8
  300. package/dist/docs/assets/scaffolding-agents.md.CRDDUtYJ.js +0 -1
  301. package/dist/docs/assets/troubleshooting.md.DYECCZiJ.js +0 -1
  302. package/dist/docs/example-agents/fsd.html +0 -41
  303. package/dist/docs/example-agents/fsd.md +0 -329
  304. package/docs/example-agents/fsd.md +0 -334
  305. /package/dist/docs/assets/{deployment.md.DX_hc3ze.lean.js → deployment.md.DoLFAzfm.lean.js} +0 -0
  306. /package/dist/docs/assets/{example-agents_approval-buddy.md.DNL83puR.lean.js → example-agents_approval-buddy.md.DmezILPg.lean.js} +0 -0
  307. /package/dist/docs/assets/{example-agents_concierge.md.MrKpQndp.lean.js → example-agents_concierge.md.BzB2b20R.lean.js} +0 -0
  308. /package/dist/docs/assets/{example-agents_knowledge-base.md.DqKqHQ9u.lean.js → example-agents_knowledge-base.md.CrA85ig-.lean.js} +0 -0
  309. /package/dist/docs/assets/{example-agents_security-reviewer.md.Bai6D0Ee.lean.js → example-agents_security-reviewer.md.74pPpWYj.lean.js} +0 -0
  310. /package/dist/docs/assets/{example-agents_weather-agent.md.lVEAbWFf.lean.js → example-agents_weather-agent.md.CaGpmw3Y.lean.js} +0 -0
  311. /package/dist/docs/assets/{guides_agent-to-agent.md.BCeVdJRJ.lean.js → guides_agent-to-agent.md.B3JIaAqz.lean.js} +0 -0
  312. /package/dist/docs/assets/{guides_convert-automation.md.D06eIzea.lean.js → guides_convert-automation.md.Bboisykk.lean.js} +0 -0
  313. /package/dist/docs/assets/{guides_mcp-oauth.md.Du0f7pGU.lean.js → guides_mcp-oauth.md.CJvrXtkN.lean.js} +0 -0
  314. /package/dist/docs/assets/{guides_slack.md.DiUmk_Oi.lean.js → guides_slack.md.mqeNKs84.lean.js} +0 -0
  315. /package/dist/docs/assets/{guides_webhooks.md.BpnIdO0i.lean.js → guides_webhooks.md.DKdA43Qm.lean.js} +0 -0
  316. /package/dist/docs/assets/{hillclimbing.md.ywF3yDAd.lean.js → hillclimbing.md.DhESf3OO.lean.js} +0 -0
  317. /package/dist/docs/assets/{quickstart.md.DsrarzEg.lean.js → quickstart.md.BrmfrrIr.lean.js} +0 -0
  318. /package/dist/docs/assets/{reference_agent-config.md.Bqylgw50.lean.js → reference_agent-config.md.Cp_x38Nl.lean.js} +0 -0
  319. /package/dist/docs/assets/{reference_connections.md.DYidrb-j.lean.js → reference_connections.md.DB6SsN6U.lean.js} +0 -0
  320. /package/dist/docs/assets/{reference_project-layout.md.CwkSbEWT.lean.js → reference_project-layout.md.WN9nwJht.lean.js} +0 -0
  321. /package/dist/docs/assets/{reference_prompt.md.DZUMtLPD.lean.js → reference_prompt.md.DnaD5dNK.lean.js} +0 -0
  322. /package/dist/docs/assets/{reference_schedules.md.DNipebiG.lean.js → reference_schedules.md.DI_JrHgq.lean.js} +0 -0
  323. /package/dist/docs/assets/{reference_skills.md.B5ZEuHfG.lean.js → reference_skills.md.BFW9retM.lean.js} +0 -0
  324. /package/dist/docs/assets/{templates_agentic-owners.md.DSJSIpWU.lean.js → templates_agentic-owners.md.DqtPdm6f.lean.js} +0 -0
@@ -1,4 +0,0 @@
1
- import{_ as t,c as a,o,ag as s}from"./chunks/framework.BCISBCiQ.js";const u=JSON.parse('{"title":"How the Agent SDK works","description":"Understand projects, sessions, event streams, channels, and runtimes in plain language.","frontmatter":{"title":"How the Agent SDK works","description":"Understand projects, sessions, event streams, channels, and runtimes in plain language."},"headers":[],"relativePath":"concepts.md","filePath":"concepts.md"}'),n={name:"concepts.md"};function r(d,e,l,i,c,h){return o(),a("div",null,[...e[0]||(e[0]=[s(`<h1 id="how-the-agent-sdk-works" tabindex="-1">How the Agent SDK works <a class="header-anchor" href="#how-the-agent-sdk-works" aria-label="Permalink to &quot;How the Agent SDK works&quot;">​</a></h1><p>An agent is a folder of instructions and capabilities. The Agent SDK discovers those files, runs conversations, and records what happened.</p><h2 id="what-happens-when-someone-sends-a-message" tabindex="-1">What happens when someone sends a message? <a class="header-anchor" href="#what-happens-when-someone-sends-a-message" aria-label="Permalink to &quot;What happens when someone sends a message?&quot;">​</a></h2><p>Follow one message through the system:</p><ol><li>A channel receives the message from HTTP, Slack, GitHub, or another webhook.</li><li>The channel starts a session or continues an existing one.</li><li>The runtime gives the model its instructions, tools, and workspace.</li><li>The model replies and can call tools along the way.</li><li>The Agent SDK appends every message and tool call to the session&#39;s event stream.</li></ol><p>The channel is the front door. The runtime does the work. The event stream is the record you inspect later.</p><h2 id="how-do-files-become-an-agent" tabindex="-1">How do files become an agent? <a class="header-anchor" href="#how-do-files-become-an-agent" aria-label="Permalink to &quot;How do files become an agent?&quot;">​</a></h2><p>Each capability has a home in the project. The path tells the Agent SDK what to load. The filename becomes the capability&#39;s name. For example, <code>agent/tools/get_weather.ts</code> creates a tool named <code>get_weather</code>.</p><table tabindex="0"><thead><tr><th>Path</th><th>What it is</th></tr></thead><tbody><tr><td><code>agent/agent.ts</code></td><td>Model and runtime settings</td></tr><tr><td><code>agent/instructions.md</code></td><td>The always-on system prompt</td></tr><tr><td><code>agent/tools/&lt;name&gt;.ts</code></td><td>Typed actions the model can call</td></tr><tr><td><code>agent/skills/*</code></td><td>Procedures loaded when needed</td></tr><tr><td><code>agent/mcp-connections/&lt;name&gt;.ts</code></td><td>Tools from external MCP servers</td></tr><tr><td><code>agent/channels/*.ts</code></td><td>HTTP, Slack, and GitHub entry points</td></tr><tr><td><code>agent/ab.ts</code> or <code>agent/ab/*.ts</code></td><td>Sticky variants and live performance metrics</td></tr><tr><td><code>evals/**/*.eval.ts</code></td><td>Repeatable checks at the project root</td></tr></tbody></table><p>Other folders add subagents, hooks, schedules, and workspace files. You don&#39;t register them elsewhere. Run <code>agent-sdk validate</code> to catch invalid files before serving the project.</p><p>See <a href="./reference/project-layout.html">Project layout</a> for every supported path.</p><h2 id="how-does-the-agent-sdk-identify-a-conversation" tabindex="-1">How does the Agent SDK identify a conversation? <a class="header-anchor" href="#how-does-the-agent-sdk-identify-a-conversation" aria-label="Permalink to &quot;How does the Agent SDK identify a conversation?&quot;">​</a></h2><p>A session is one durable conversation. It has two identifiers:</p><ul><li><strong><code>continuationToken</code></strong> tells a channel which conversation to resume. A Slack channel can use its thread ID. A GitHub channel can use the pull request. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up.</li><li><strong><code>sessionId</code></strong> identifies the stored session. Use it to stream events, inspect the session, resolve approvals, or bind a tool call to the session.</li></ul><p>Use the continuation token to keep talking. Use the session ID to observe or manage the conversation.</p><h2 id="how-do-i-see-what-an-agent-did" tabindex="-1">How do I see what an agent did? <a class="header-anchor" href="#how-do-i-see-what-an-agent-did" aria-label="Permalink to &quot;How do I see what an agent did?&quot;">​</a></h2><p>Each session writes an append-only NDJSON file: <code>sessions/&lt;id&gt;/events.ndjson</code>. It includes:</p><ul><li>Messages and streamed text</li><li>Requested tool calls and their results</li><li>Approval requests and decisions</li><li>Turn completion and token usage</li></ul><p>Sessions and their event streams survive server restarts. The playground renders the stream. Evals assert against it. The <code>agent-sdk trajectory</code> command turns a saved stream into a short summary.</p><p>When a run surprises you, inspect its event stream first. See <a href="./reference/sessions.html">Sessions and streaming</a> for every event.</p><h2 id="what-does-a-channel-control" tabindex="-1">What does a channel control? <a class="header-anchor" href="#what-does-a-channel-control" aria-label="Permalink to &quot;What does a channel control?&quot;">​</a></h2><p>A channel connects the agent to a surface such as HTTP, Slack, GitHub, or a custom webhook. It controls:</p><ul><li>Routes and input schemas</li><li>Authentication</li><li>Conversation identity</li><li>How replies return to the user</li></ul><p>The built-in HTTP session API is always available. Custom routes accept loopback callers by default. Add an auth policy before sharing them over a network.</p><p>Channels should also prepare deterministic input for the model. For example, a GitHub channel can fetch the pull request, collect the diff, and seed the workspace before the turn starts. The model can then focus on the review instead of gathering files.</p><p>See <a href="./reference/channels.html">Channels</a> for route and authentication details.</p><h2 id="where-does-a-turn-run" tabindex="-1">Where does a turn run? <a class="header-anchor" href="#where-does-a-turn-run" aria-label="Permalink to &quot;Where does a turn run?&quot;">​</a></h2><p>Choose a runtime in <code>agent/agent.ts</code>:</p><table tabindex="0"><thead><tr><th></th><th>Local (default)</th><th>Cloud</th></tr></thead><tbody><tr><td>Turn runs on</td><td>The server host</td><td>A Cursor cloud agent</td></tr><tr><td>Server tools</td><td>Supported</td><td>Supported when the server has <code>--public-url</code> or <code>--cloud-tools-url</code>; the cloud turn reaches them over authenticated HTTP MCP. Without one of those flags, the server warns and cloud turns omit them.</td></tr><tr><td>Approvals (<code>needsApproval</code>)</td><td>Supported</td><td>Not supported (local runtime only)</td></tr><tr><td>Agent tool scripts</td><td>Supported</td><td>Supported</td></tr><tr><td>Skills</td><td>Added to the session workspace</td><td>Available automatically</td></tr><tr><td>Seeded files</td><td>Added to the session workspace</td><td>Ignored</td></tr><tr><td>Repository</td><td>You provide it</td><td>The cloud agent checks it out</td></tr></tbody></table><p>Use the local runtime when the host has the tools and files the agent needs. Use the cloud runtime when each turn needs an isolated repository checkout. <code>agent-sdk validate</code> warns when a cloud agent uses a local-only capability.</p><p>See <a href="./guides/cloud-runtime.html">Cloud runtime</a> for setup and trade-offs.</p><h2 id="what-files-can-a-local-session-access" tabindex="-1">What files can a local session access? <a class="header-anchor" href="#what-files-can-a-local-session-access" aria-label="Permalink to &quot;What files can a local session access?&quot;">​</a></h2><p>Each local session gets its own workspace. The Agent SDK writes the instructions as <code>AGENTS.md</code>, installs authored skills, copies sandbox files, and adds agent tool scripts.</p><p>The workspace is a real Cursor project. It can inherit <code>AGENTS.md</code> and <code>.cursor</code> settings from parent directories. Nested git checkouts default <code>local.cwd</code> to <code>~/.cache/agent-serve/&lt;dir&gt;</code>. Point <code>cwd</code> at a checkout only when the agent should inherit that tree. <code>run</code> and <code>eval</code> already use a temporary state root.</p><p>Durable local state uses this shape:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>&lt;project&gt;/.agent-serve/</span></span>
2
- <span class="line"><span> sessions/&lt;id&gt;/events.ndjson</span></span>
3
- <span class="line"><span> sessions/&lt;id&gt;/workspace/</span></span>
4
- <span class="line"><span> traces/&lt;sessionId&gt;.ndjson</span></span></code></pre></div><h2 id="how-can-one-agent-call-another" tabindex="-1">How can one agent call another? <a class="header-anchor" href="#how-can-one-agent-call-another" aria-label="Permalink to &quot;How can one agent call another?&quot;">​</a></h2><p>Every mounted agent also serves MCP at <code>/&lt;slug&gt;/v1/mcp</code>. Another agent or MCP client can use <code>ask</code>, <code>check</code>, and <code>call_tool</code> to delegate work. A peer MCP connection such as <code>defineConnection({ agent: &quot;weather-agent&quot; })</code> adds those tools to the calling agent.</p><p>See <a href="./guides/agent-to-agent.html">Agent-to-agent</a> for a complete example.</p><h2 id="which-rules-prevent-common-setup-problems" tabindex="-1">Which rules prevent common setup problems? <a class="header-anchor" href="#which-rules-prevent-common-setup-problems" aria-label="Permalink to &quot;Which rules prevent common setup problems?&quot;">​</a></h2><ul><li>Use Node 22.13 or newer. Bun isn&#39;t supported.</li><li>Put evals under the project-root <code>evals/</code> directory, not <code>agent/evals/</code>.</li><li>Run a TypeScript check before shipping. <code>validate</code> and <code>run</code> execute TypeScript but don&#39;t type-check it.</li><li>Return JSON-shaped values from tool <code>execute</code> functions.</li><li>Keep local session workspaces away from parent rules you don&#39;t want the agent to inherit.</li><li>Sign in or set <code>CURSOR_API_KEY</code> before starting a model turn. Discovery, validation, direct tool calls, and server startup work without a credential.</li></ul><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./quickstart.html">Quickstart</a></li><li><a href="./reference/project-layout.html">Project layout</a></li><li><a href="./reference/sessions.html">Sessions and streaming</a></li><li><a href="./reference/channels.html">Channels</a></li><li><a href="./ab.html">Live A/B metrics</a></li><li><a href="./guides/cloud-runtime.html">Cloud runtime</a></li></ul>`,43)])])}const m=t(n,[["render",r]]);export{u as __pageData,m as default};
@@ -1,15 +0,0 @@
1
- import{_ as t,c as s,o as a,ag as i}from"./chunks/framework.BCISBCiQ.js";const u=JSON.parse('{"title":"Hand PR triage to managed remote agents","description":"Coordinate local chat, per-PR remote sessions, GitHub wake buffering, workflow MCP enrollment, durable affinity, findings, and reminders.","frontmatter":{"title":"Hand PR triage to managed remote agents","description":"Coordinate local chat, per-PR remote sessions, GitHub wake buffering, workflow MCP enrollment, durable affinity, findings, and reminders."},"headers":[],"relativePath":"example-agents/fsd.md","filePath":"example-agents/fsd.md"}'),o={name:"example-agents/fsd.md"};function n(r,e,l,d,h,c){return a(),s("div",null,[...e[0]||(e[0]=[i(`<h1 id="hand-pr-triage-to-managed-remote-agents" tabindex="-1">Hand PR triage to managed remote agents <a class="header-anchor" href="#hand-pr-triage-to-managed-remote-agents" aria-label="Permalink to &quot;Hand PR triage to managed remote agents&quot;">​</a></h1><p>The remote PR coordinator keeps chat and routing on the local serve host, then hands each pull request to a managed remote agent with a real checkout. The same remote conversation resumes when a user drives the PR again, GitHub reports a change, or a merge-conflict reminder fires.</p><p>This example is Cursor-internal. For your own repos, scaffold <a href="./../templates/pr-autofixer.html">PR autofixer</a> instead.</p><p>The workflow backend enrolls each remote run with a workflow MCP. Its tools and the host&#39;s findings routes read and write the same external findings service.</p><p>Use this example when repository work is too heavy or concurrent for local worktrees, but the host should still own intake, session identity, policy, and bookkeeping.</p><p><a href="./../../examples/fsd/">Browse the current coordinator source.</a></p><h2 id="resume-one-remote-agent-across-every-pr-wake" tabindex="-1">Resume one remote agent across every PR wake <a class="header-anchor" href="#resume-one-remote-agent-across-every-pr-wake" aria-label="Permalink to &quot;Resume one remote agent across every PR wake&quot;">​</a></h2><p>The coordinator uses a hybrid runtime:</p><ul><li>Ordinary playground and Slack chat run locally.</li><li>The <code>drive_pr</code> server tool creates a remote session for one PR.</li><li>The remote worker gets the repository and PR reference.</li><li>An <code>agent.bound</code> hook records the remote run id and enrolls the run into a workflow MCP.</li><li>Webhooks and reminders resume the same remote agent through durable PR-to-agent affinity.</li></ul><p>No other example moves one logical conversation across local chat, remote execution, event wakes, and timed follow-ups.</p><h2 id="follow-a-chat-request" tabindex="-1">Follow a chat request <a class="header-anchor" href="#follow-a-chat-request" aria-label="Permalink to &quot;Follow a chat request&quot;">​</a></h2><ol><li>A user asks local chat or Slack to drive a PR.</li><li>The root model calls <code>drive_pr</code> with the PR, mode, and optional hint.</li><li>The tool calls <code>ctx.send(&quot;drive&quot;, ...)</code> with a per-session <code>cloud</code> block to attach the PR.</li><li>The Agent SDK creates or resumes the <code>drive</code> session keyed by <code>pr:owner/repo#N</code>.</li><li>The remote runtime provisions the agent and emits <code>agent.bound</code>.</li><li>The enrollment hook writes PR affinity and calls the workflow backend to attach run-scoped MCP tools.</li><li><code>drive_pr</code> waits for remote binding, then returns the agent id and URL. If binding exceeds its wait window, those fields can be <code>null</code> while work continues.</li><li>The remote agent reads the host-prepared PR brief, checks unresolved state, and records findings through the workflow MCP.</li><li>The host forwards a validated fallback output block when MCP wasn&#39;t available for the turn.</li></ol><p>The local chat agent doesn&#39;t have the target checkout, <code>gh</code>, <code>git</code>, or the workflow MCP. Its job is coordination.</p><p>A request for a merged or closed PR finishes before provisioning. That result has <code>status: &quot;finished&quot;</code> and no remote session.</p><h2 id="map-the-framework-features" tabindex="-1">Map the framework features <a class="header-anchor" href="#map-the-framework-features" aria-label="Permalink to &quot;Map the framework features&quot;">​</a></h2><table tabindex="0"><thead><tr><th>Capability</th><th>Source</th><th>Role</th></tr></thead><tbody><tr><td>Hybrid config</td><td><a href="../../examples/fsd/agent/agent.ts"><code>agent/agent.ts</code></a></td><td>Keep chat local, set remote-runtime defaults, disable automatic PR creation, and isolate local harness workspaces.</td></tr><tr><td>Root instructions</td><td><a href="./../../examples/fsd/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Separate local coordination from remote triage and define suggest/apply policy.</td></tr><tr><td>Drive tool</td><td><a href="../../examples/fsd/agent/tools/drive_pr.ts"><code>agent/tools/drive_pr.ts</code></a></td><td>Hand a chat request to the <code>drive</code> channel and wait for remote binding.</td></tr><tr><td>Drive channel</td><td><a href="../../examples/fsd/agent/channels/drive.ts"><code>agent/channels/drive.ts</code></a></td><td>Start remote work and expose findings read/write routes.</td></tr><tr><td>GitHub channel</td><td><a href="../../examples/fsd/agent/channels/github.ts"><code>agent/channels/github.ts</code></a></td><td>Buffer PR, comment, review, check, and status wakes.</td></tr><tr><td>Slack channel</td><td><a href="../../examples/fsd/agent/channels/slack.ts"><code>agent/channels/slack.ts</code></a></td><td>Route Slack requests to the local coordinator.</td></tr><tr><td>Hooks</td><td><a href="../../examples/fsd/agent/hooks/enroll-fsd.ts"><code>agent/hooks/enroll-fsd.ts</code></a>, <a href="../../examples/fsd/agent/hooks/record-outputs.ts"><code>agent/hooks/record-outputs.ts</code></a></td><td>Bind remote identity, enroll MCP, and forward fallback findings.</td></tr><tr><td>Affinity and buffering</td><td><a href="../../examples/fsd/agent/lib/pr-affinity.ts"><code>agent/lib/pr-affinity.ts</code></a>, <a href="../../examples/fsd/agent/lib/webhook-buffer.ts"><code>agent/lib/webhook-buffer.ts</code></a></td><td>Persist PR identity, sticky mode, and pending wakes.</td></tr><tr><td>Reminders</td><td><a href="../../examples/fsd/agent/lib/merge-conflict-watch.ts"><code>agent/lib/merge-conflict-watch.ts</code></a></td><td>Recheck merge conflicts every 30 minutes.</td></tr><tr><td>Workflow client</td><td><a href="../../examples/fsd/agent/lib/fsd-platform.ts"><code>agent/lib/fsd-platform.ts</code></a></td><td>Enroll external runs and read or record findings.</td></tr><tr><td>Storage</td><td><a href="../../examples/fsd/agent/storage.ts"><code>agent/storage.ts</code></a></td><td>Persist sessions and events with <code>cursorHostedStorage</code>.</td></tr></tbody></table><p>The coordinator has no authored skill, subagent, MCP connection, static schedule, A/B experiment, eval, or tool approval.</p><p>The workflow MCP is dynamic. Backend enrollment attaches it to the remote run, so there is no file under <code>agent/mcp-connections/</code>.</p><h2 id="understand-local-and-remote-workspaces" tabindex="-1">Understand local and remote workspaces <a class="header-anchor" href="#understand-local-and-remote-workspaces" aria-label="Permalink to &quot;Understand local and remote workspaces&quot;">​</a></h2><p>The root config sets <code>runtime: &quot;local&quot;</code> because <code>drive_pr</code> is a server tool. It also supplies remote-runtime defaults through the <code>cloud</code> configuration:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
2
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> cwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">homedir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;.cache&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;agent-serve&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;fsd&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
3
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">},</span></span>
4
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cloud</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
5
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> env</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;cloud&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
6
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> autoCreatePR</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
7
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">},</span></span></code></pre></div><p>The local cwd sits outside the monorepo, so inherited repository instructions don&#39;t affect coordinator chat.</p><p>Remote sessions get a repository attachment with the target PR. The worker starts from the PR base and creates an automation side branch from the PR head only when code context or a fix is needed. The serve host never checks out target code.</p><h2 id="prepare-access" tabindex="-1">Prepare access <a class="header-anchor" href="#prepare-access" aria-label="Permalink to &quot;Prepare access&quot;">​</a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime user credential.</li><li>Access to a managed remote runtime.</li><li>Access to the target GitHub PR.</li><li>Access to the workflow backend and findings store.</li></ul><p>Keep the affinity and webhook-buffer files on durable storage for a long-lived host.</p><h2 id="validate-without-starting-remote-work" tabindex="-1">Validate without starting remote work <a class="header-anchor" href="#validate-without-starting-remote-work" aria-label="Permalink to &quot;Validate without starting remote work&quot;">​</a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd</span></span>
8
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span>
9
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> github</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> events</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>These commands inspect discovery and declared GitHub events. They don&#39;t provision a remote agent.</p><h2 id="choose-suggest-or-apply" tabindex="-1">Choose suggest or apply <a class="header-anchor" href="#choose-suggest-or-apply" aria-label="Permalink to &quot;Choose suggest or apply&quot;">​</a></h2><p>Every PR has a sticky mode:</p><table tabindex="0"><thead><tr><th>Mode</th><th>Required remote behavior</th></tr></thead><tbody><tr><td><code>suggest</code></td><td>May create verified commits on the VM&#39;s local side branch. Instructions require no pushes, comments, PR edits, or workflow actions. Records exact fixes and actions as findings for the owner.</td></tr><tr><td><code>apply</code></td><td>Pushes verified fixes to the existing PR head and may update metadata, reply to threads, mark a draft ready, rebase, or rerun CI.</td></tr></tbody></table><p>The remote instructions forbid merging, enabling auto-merge, force-pushing, and opening a new PR in both modes. <code>autoCreatePR: false</code> also disables the SDK&#39;s automatic PR creation. The other restrictions are prompt policy, not a deterministic host gate. <code>suggest</code> is the default.</p><p>The selected mode is stored beside PR affinity. Webhooks and reminders reuse it. Re-driving a PR can change the host-side mode. Backend enrollment records the mode at first enrollment, so each later host prompt repeats the current authoritative mode.</p><div class="caution custom-block github-alert"><p class="custom-block-title">CAUTION</p><p><code>apply</code> writes to the user&#39;s PR branch and triggers CI. Use <code>suggest</code> for development. Both modes provision a billed remote agent and can write structured findings to the findings service. <code>drive_pr</code> has no approval gate, and suggest/apply restrictions depend on the remote agent following its instructions.</p></div><h2 id="start-a-suggest-mode-drive" tabindex="-1">Start a suggest-mode drive <a class="header-anchor" href="#start-a-suggest-mode-drive" aria-label="Permalink to &quot;Start a suggest-mode drive&quot;">​</a></h2><p>Run the host:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd</span></span></code></pre></div><p>From chat:</p><blockquote><p>Drive <a href="https://github.com/owner/repo/pull/123" target="_blank" rel="noreferrer">https://github.com/owner/repo/pull/123</a> in suggest mode.</p></blockquote><p>Or call the coordinator tool:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> drive_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
10
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
11
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;pr&quot;:&quot;https://github.com/owner/repo/pull/123&quot;,&quot;mode&quot;:&quot;suggest&quot;}&#39;</span></span></code></pre></div><p>For an open PR, the tool waits up to 60 seconds for remote binding and returns:</p><ul><li>the normalized PR label,</li><li>session and continuation ids,</li><li>the remote-agent id and URL when binding completes in that window,</li><li><code>status: &quot;started&quot;</code>, and</li><li>the merge-conflict reminder id.</li></ul><p>It doesn&#39;t wait for findings. A slow binding can return <code>null</code> identifiers. Open the returned agent URL when present to follow the remote run.</p><h2 id="use-the-http-drive-surface" tabindex="-1">Use the HTTP drive surface <a class="header-anchor" href="#use-the-http-drive-surface" aria-label="Permalink to &quot;Use the HTTP drive surface&quot;">​</a></h2><p>The custom channel starts the same orchestration:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
12
- <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/fsd/v1/channels/drive/</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
13
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;content-type: application/json&#39;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
14
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;pr&quot;:&quot;owner/repo#123&quot;,&quot;mode&quot;:&quot;suggest&quot;}&#39;</span></span></code></pre></div><p>This route returns as soon as the channel session exists. The remote-agent id can still be <code>null</code> at that point. Triage continues in the background.</p><p>Read findings later:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
15
- <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;http://127.0.0.1:3000/fsd/v1/channels/drive/findings?pr=owner/repo%23123&#39;</span></span></code></pre></div><p>The external findings service is the source of truth. The local host doesn&#39;t keep a second findings database.</p><p>The channel also exposes <code>POST /findings</code> as a testing surface. It validates outputs, then writes them to the findings service for a PR already bound by this host. The route has no approval gate. Keep it under the default loopback auth or another trusted boundary.</p><h2 id="keep-one-remote-agent-per-pr" tabindex="-1">Keep one remote agent per PR <a class="header-anchor" href="#keep-one-remote-agent-per-pr" aria-label="Permalink to &quot;Keep one remote agent per PR&quot;">​</a></h2><p>Within the <code>drive</code> channel, the stable continuation token <code>pr:owner/repo#N</code> resumes the same session. GitHub sessions are scoped to another channel, so a continuation token alone can&#39;t bridge them.</p><p>The enrollment hook closes that gap:</p><ol><li>Read the PR from the continuation token or host-authored session title.</li><li>Record PR to <code>sdkAgentId</code> affinity after <code>agent.bound</code>.</li><li>Seed later sessions with the same remote id.</li><li>Retry workflow MCP enrollment after a completed turn when the first RPC failed.</li></ol><p>This lets Slack, HTTP drive, GitHub, and reminders talk to one remote conversation without sharing one channel session.</p><h2 id="buffer-github-wakes" tabindex="-1">Buffer GitHub wakes <a class="header-anchor" href="#buffer-github-wakes" aria-label="Permalink to &quot;Buffer GitHub wakes&quot;">​</a></h2><p>The GitHub channel handles pull requests, comments, reviews, check suites, check runs, and selected status events. It doesn&#39;t send payload details to the model. It asks the remote agent to refresh live source of truth.</p><p>The buffer:</p><ul><li>groups events by PR,</li><li>waits three seconds for a burst to settle,</li><li>re-buffers while CI settles,</li><li>skips a flush when the PR session is busy,</li><li>tries to write its snapshot before acknowledging a wake, and</li><li>restores pending entries when the channel starts.</li></ul><p>Closing a PR discards its pending entry and cancels its reminders.</p><p>Snapshot persistence is best-effort. Write failures are swallowed silently, so a delivery can still be acknowledged without a durable snapshot.</p><p>This is the high-volume counterpart to a direct <code>{ auth }</code> GitHub wake. See <a href="./../guides/github.html#handle-high-event-volume">GitHub</a> for the reusable pattern.</p><h2 id="add-merge-conflict-checks" tabindex="-1">Add merge-conflict checks <a class="header-anchor" href="#add-merge-conflict-checks" aria-label="Permalink to &quot;Add merge-conflict checks&quot;">​</a></h2><p>Starting a drive arms one recurring reminder per PR. Every 30 minutes the host checks mergeability:</p><ul><li>closed or merged stops the reminder,</li><li>clean skips delivery,</li><li>conflicting sends a follow-up to the owning session, and</li><li>a busy session skips the wake.</li></ul><p>This uses runtime reminders, not a static <code>agent/schedules/</code> file. The host creates, lists, replaces, and cancels reminders through <code>host.reminders</code>. Development mode doesn&#39;t fire reminder timers automatically. Dispatch one through the dev reminder endpoint for a manual proof, or use non-dev <code>serve</code> to run the 30-minute cadence.</p><p>The reminder&#39;s <code>run</code> handler lives in memory. After a host restart, the Agent SDK disarms it with <code>handler_lost_on_restart</code>; a later drive or webhook path can arm a fresh handler. Persisted reminder metadata alone doesn&#39;t keep the check running.</p><h2 id="record-findings-with-mcp-or-a-fallback" tabindex="-1">Record findings with MCP or a fallback <a class="header-anchor" href="#record-findings-with-mcp-or-a-fallback" aria-label="Permalink to &quot;Record findings with MCP or a fallback&quot;">​</a></h2><p>After enrollment, the remote agent receives workflow tools for:</p><ul><li>recording and updating outputs,</li><li>listing current outputs,</li><li>reading PR metadata,</li><li>reading CI state, and</li><li>reading review comments.</li></ul><p>The main output is a structured workflow suggestion or code-change reference. The remote prompt requires findings as soon as each action becomes clear.</p><p>If enrollment races or MCP is unavailable, the agent writes one fenced fallback JSON block. The host validates allowed kinds, actions, statuses, and the 140-character finding body before forwarding it to the same findings service. The output hook catches fallback blocks from webhook and reminder turns.</p><h2 id="verify-the-host-logic" tabindex="-1">Verify the host logic <a class="header-anchor" href="#verify-the-host-logic" aria-label="Permalink to &quot;Verify the host logic&quot;">​</a></h2><p>The coordinator has no filesystem evals. Its unit tests cover mode parsing, drive orchestration, affinity, webhook durability, CI settlement, output parsing, reminders, and Slack configuration:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> exec</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> vitest</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/fsd/agent/lib</span></span></code></pre></div><p>Use those tests for host policy. Use a dedicated test PR and suggest mode for the end-to-end remote path.</p><h2 id="build-another-hybrid-coordinator" tabindex="-1">Build another hybrid coordinator <a class="header-anchor" href="#build-another-hybrid-coordinator" aria-label="Permalink to &quot;Build another hybrid coordinator&quot;">​</a></h2><p>Use this architecture when each work item needs a real checkout:</p><ol><li>Keep conversational intake local.</li><li>Open a remote session only after the request identifies a work item.</li><li>Give the work item a stable continuation key.</li><li>Persist its remote-agent id for cross-channel resume.</li><li>Coalesce noisy events before spending another turn.</li><li>Put the current mode and permissions in every host prompt.</li><li>Record outputs incrementally in a durable sink.</li><li>Add reminders for state requiring periodic rechecks.</li></ol><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to &quot;Where to go next&quot;">​</a></h2><ul><li><a href="./../guides/cloud-runtime.html">Cloud runtime</a></li><li><a href="./../guides/github.html">GitHub</a></li><li><a href="./../guides/webhooks.html">Webhooks and custom channels</a></li><li><a href="./../reference/schedules.html">Schedules and reminders</a></li><li><a href="./../reference/sessions.html">Sessions and streaming</a></li><li><a href="./../deployment.html">Deployment</a></li></ul>`,85)])])}const k=t(o,[["render",n]]);export{u as __pageData,k as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as s,o as a,ag as i}from"./chunks/framework.BCISBCiQ.js";const u=JSON.parse('{"title":"Hand PR triage to managed remote agents","description":"Coordinate local chat, per-PR remote sessions, GitHub wake buffering, workflow MCP enrollment, durable affinity, findings, and reminders.","frontmatter":{"title":"Hand PR triage to managed remote agents","description":"Coordinate local chat, per-PR remote sessions, GitHub wake buffering, workflow MCP enrollment, durable affinity, findings, and reminders."},"headers":[],"relativePath":"example-agents/fsd.md","filePath":"example-agents/fsd.md"}'),o={name:"example-agents/fsd.md"};function n(r,e,l,d,h,c){return a(),s("div",null,[...e[0]||(e[0]=[i("",85)])])}const k=t(o,[["render",n]]);export{u as __pageData,k as default};
@@ -1,2 +0,0 @@
1
- import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.BCISBCiQ.js";const m=JSON.parse('{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches.","frontmatter":{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches."},"headers":[],"relativePath":"example-agents/index.md","filePath":"example-agents/index.md"}'),s={name:"example-agents/index.md"};function n(i,e,d,l,h,c){return r(),a("div",null,[...e[0]||(e[0]=[o(`<h1 id="choose-the-right-agent-sdk-example" tabindex="-1">Choose the right Agent SDK example <a class="header-anchor" href="#choose-the-right-agent-sdk-example" aria-label="Permalink to &quot;Choose the right Agent SDK example&quot;">​</a></h1><p>The examples progress from one-channel assistants to durable, event-driven workflows. Start with the smallest agent for your use case. Each guide explains its request flow, framework features, verification path, and reusable design.</p><p>The source projects live under <a href="./../../examples/"><code>examples/</code></a>. Run the commands below from <code>packages/agent-serve</code>. See <a href="/docs/#run-the-cli">Run the CLI</a> if the <code>agent-sdk</code> command isn&#39;t installed.</p><h2 id="compare-the-examples" tabindex="-1">Compare the examples <a class="header-anchor" href="#compare-the-examples" aria-label="Permalink to &quot;Compare the examples&quot;">​</a></h2><table tabindex="0"><thead><tr><th>Agent</th><th>Runtime</th><th>Intake</th><th>Framework focus</th><th>What sets it apart</th></tr></thead><tbody><tr><td><a href="./weather-agent.html">Weather agent</a></td><td>Cloud</td><td>HTTP and two Slack transports</td><td>Tools, stdio MCP, skill, subagent, schedule, hooks, A/B, and evals</td><td>It demonstrates the broad cloud-runtime surface in one domain.</td></tr><tr><td><a href="./slack-agent.html">Slack agent</a></td><td>Local</td><td>Account-linked Slack</td><td>Channel identity, threads, and suggested prompts</td><td>It reaches Slack without authored tools.</td></tr><tr><td><a href="./concierge.html">Concierge</a></td><td>Local</td><td>Built-in HTTP</td><td>Peer MCP and multi-agent serving</td><td>It delegates to a separate agent with its own tools, sessions, and context.</td></tr><tr><td><a href="./benny.html">Playbook router</a></td><td>Local with repo context</td><td>Two Slack transports</td><td>Channel watching, inherited skills, custom cwd, and an eval</td><td>An allowlisted Slack channel becomes an intake queue for repo playbooks.</td></tr><tr><td><a href="./oncall.html">Alert investigator</a></td><td>Local</td><td>Watched Slack alerts channel</td><td>Bot-post channel watching, per-thread debounce, reminder tools, and host Slack calls</td><td>Every alert gets a thread-pinned investigation that schedules its own re-checks.</td></tr><tr><td><a href="./bugbot.html">PR evidence reviewer</a></td><td>Local</td><td>Custom HTTP and Slack</td><td>Host tool, skill, seeded workspaces, and an eval</td><td>The model receives a prepared diff-first evidence tree instead of a checkout.</td></tr><tr><td><a href="./approval-buddy.html">Approval Buddy</a></td><td>Local</td><td>GitHub and Slack</td><td>Policy tools, two subagents, durable storage, and evals</td><td>Code decides whether a PR may be approved. Reviews stay informational.</td></tr><tr><td><a href="./security-reviewer.html">Security Reviewer</a></td><td>Local host pipeline</td><td>GitHub and chat</td><td>Staged tools, parallel SDK agents, progress UI, durable storage, A/B, and evals</td><td>Lives in <code>factory/security-reviewer/</code>. Reviewers and triage overlap while the playground shows every stage.</td></tr><tr><td><a href="./fsd.html">Remote PR coordinator</a></td><td>Local coordinator and remote PR sessions</td><td>HTTP, GitHub, and Slack</td><td>Remote handoff, hooks, affinity, buffering, reminders, and workflow MCP</td><td>One remote conversation follows a PR across chat, webhooks, and timed wakes.</td></tr><tr><td><a href="./knowledge-base.html">Knowledge base</a></td><td>Local</td><td>Built-in HTTP chat</td><td>Durable host-side state, a conventions skill, a schedule, unit tests, and evals</td><td>People curate shared facts in chat, and fresh sessions retrieve them from markdown.</td></tr><tr><td><a href="./codebase-wiki.html">Codebase wiki</a></td><td>Local</td><td>GitHub and chat</td><td>Task-dispatch webhooks, seeded digests, a mapping skill, a schedule, and evals</td><td>Merged PRs accumulate into per-feature wiki pages with a daily digest.</td></tr><tr><td><a href="./codeowners-review.html">Codeowners review</a></td><td>Local</td><td>GitHub, chat, and fixtures</td><td>Ownership routing in code, playbook data files, parallel subagents, and evals</td><td>Each product area reviews with its own playbook, and verdicts aggregate mechanically.</td></tr></tbody></table><h2 id="pick-a-learning-path" tabindex="-1">Pick a learning path <a class="header-anchor" href="#pick-a-learning-path" aria-label="Permalink to &quot;Pick a learning path&quot;">​</a></h2><p>Use this order when you want to learn the Agent SDK one capability at a time:</p><ol><li>Start with <a href="./weather-agent.html">Weather agent</a> to explore the filesystem conventions and cloud runtime.</li><li>Strip the project back to <a href="./slack-agent.html">Slack agent</a> to see the minimum channel surface.</li><li>Read <a href="./benny.html">Playbook router</a> when Slack should route requests into repo playbooks.</li><li>Continue to <a href="./oncall.html">Alert investigator</a> when the intake is bot posts and the agent must pace its own engagement and re-checks.</li><li>Add composition with <a href="./concierge.html">Concierge</a>.</li><li>Study <a href="./bugbot.html">PR evidence reviewer</a> before giving a model repository evidence.</li><li>Move policy into code with <a href="./approval-buddy.html">Approval Buddy</a>.</li><li>Compare <a href="./security-reviewer.html">Security Reviewer</a> and <a href="./fsd.html">Remote PR coordinator</a> for host-side versus remote PR work.</li><li>See parallel subagent delegation carry team judgment in <a href="./codeowners-review.html">Codeowners review</a>.</li><li>Curate team context through conversation with <a href="./knowledge-base.html">Knowledge base</a>, then let GitHub events maintain product documentation in <a href="./codebase-wiki.html">Codebase wiki</a>.</li></ol><h2 id="common-prerequisites" tabindex="-1">Common prerequisites <a class="header-anchor" href="#common-prerequisites" aria-label="Permalink to &quot;Common prerequisites&quot;">​</a></h2><p>All examples require:</p><ul><li>Node 22.13 or newer. Don&#39;t run the Agent SDK under Bun.</li><li>Workspace dependencies installed.</li><li>An agent-runtime credential for model turns.</li></ul><p>Several examples need more:</p><ul><li>Account-linked Slack channels require a connected host account.</li><li>Alert investigator needs a dedicated Socket Mode app with channel-post events and membership in the watched alerts channel.</li><li>GitHub examples require access to the target repository. Codebase wiki and Codeowners review call the host <code>gh</code> CLI for PR data; the codeowners fixtures run without network.</li><li>Example agents use <code>cursorHostedStorage</code> (<code>agent/storage.ts</code>) for Cursor-hosted session storage (control-plane proxy).</li><li>Remote PR coordinator starts remote agent sessions and needs access to its workflow backend.</li></ul><p>Each guide lists its own credentials, services, and side effects.</p><h2 id="validate-any-example" tabindex="-1">Validate any example <a class="header-anchor" href="#validate-any-example" aria-label="Permalink to &quot;Validate any example&quot;">​</a></h2><p>Discovery commands don&#39;t start a model turn:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span></span>
2
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>Start one development server with <code>agent-sdk dev examples/&lt;name&gt;</code>. Concierge depends on Weather agent, so its guide creates an isolated two-project mount. Don&#39;t mount the whole examples directory to test one agent; several advanced examples subscribe to live GitHub events.</p><h2 id="read-by-framework-feature" tabindex="-1">Read by framework feature <a class="header-anchor" href="#read-by-framework-feature" aria-label="Permalink to &quot;Read by framework feature&quot;">​</a></h2><ul><li><a href="./../concepts.html">Concepts</a> explains filesystem discovery and runtime boundaries.</li><li><a href="./../reference/project-layout.html">Project layout</a> lists every authored folder.</li><li><a href="./../reference/tools.html">Tools</a>, <a href="./../reference/channels.html">channels</a>, and <a href="./../reference/connections.html">MCP connections</a> cover the core extension points.</li><li><a href="./../evals.html">Evals</a> and <a href="./../ab.html">live A/B metrics</a> cover measured iteration.</li><li><a href="./../deployment.html">Deployment</a> covers credentials, auth, storage, and hosting.</li></ul>`,20)])])}const u=t(s,[["render",n]]);export{m as __pageData,u as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.BCISBCiQ.js";const m=JSON.parse('{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches.","frontmatter":{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches."},"headers":[],"relativePath":"example-agents/index.md","filePath":"example-agents/index.md"}'),s={name:"example-agents/index.md"};function n(i,e,d,l,h,c){return r(),a("div",null,[...e[0]||(e[0]=[o("",20)])])}const u=t(s,[["render",n]]);export{m as __pageData,u as default};
@@ -1,14 +0,0 @@
1
- import{_ as s,c as t,o as a,ag as i}from"./chunks/framework.BCISBCiQ.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),o={name:"reference/hooks.md"};function n(d,e,r,h,l,c){return a(),t("div",null,[...e[0]||(e[0]=[i(`<h1 id="hooks" tabindex="-1">Hooks <a class="header-anchor" href="#hooks" aria-label="Permalink to &quot;Hooks&quot;">​</a></h1><p>A hook is an observe-only subscriber to the session event stream. Hooks run after each event is recorded and fanned out (file persistence flushes in the background). That makes them the home for audit logging, metrics, mirroring transcripts into your own store, and maintaining derived state. Handler errors are logged and never fatal. A hook can&#39;t modify events, inject context into the next turn, or block a turn.</p><p>For deterministic context composition before the model runs, use the host path that already owns the wake: channel handlers (fetch, <code>callTool</code>, <code>workspaceFiles</code>, and the message you pass to <code>send</code>), plus <code>instructions.md</code>, skills, and <code>sandbox/workspace/</code> seed files. Hooks observe what happened; they do not assemble the prompt.</p><p>Author <code>agent/hooks/&lt;name&gt;.ts</code> with <code>defineHook</code> from <code>@cursor/july/hooks</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineHook } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/hooks&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
2
- <span class="line"></span>
3
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineHook</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
4
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> events: {</span></span>
5
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;turn.completed&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">event</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ctx</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
6
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> prior</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.kv.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;last-result&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
7
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> notes</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.files.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">read</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;notes.md&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
8
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;turn done&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, ctx.session.id, event.data.usage, prior, notes);</span></span>
9
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
10
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;turn.failed&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">event</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ctx</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
11
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // page, count, or record</span></span>
12
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
13
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
14
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Keys are event types (the full list is in the <a href="./sessions.html#which-events-can-i-stream">event vocabulary</a>), or <code>&quot;*&quot;</code> for everything. Handlers receive the event with its envelope (<code>index</code>, <code>sessionId</code>, <code>turnId?</code>, <code>at</code>) and a <code>HookContext</code>:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>ctx.session</code></td><td>Read-only session info: id, channel, mode, auth</td></tr><tr><td><code>ctx.agent</code></td><td><code>{ name }</code> of the agent the event belongs to</td></tr><tr><td><code>ctx.channel</code></td><td><code>{ id, continuationToken }</code> for the owning channel</td></tr><tr><td><code>ctx.stateRoot</code></td><td>The agent&#39;s durable state root. Prefer <code>ctx.host.kv</code> / <code>ctx.host.files</code> for derived state; this tree resets on hosted replace</td></tr><tr><td><code>ctx.host</code></td><td>Shared host services; same as a tool&#39;s <code>ctx.host</code>. Pull JSON with <code>ctx.host.kv</code> and file-shaped state with <code>ctx.host.files</code> (session-bound by default; pass <code>{ scope: &quot;deployment&quot; }</code> for agent-wide files)</td></tr><tr><td><code>ctx.artifacts</code></td><td>Session-bound <a href="./artifacts.html">artifacts</a> facade: <code>tag</code> auto-fills the session</td></tr></tbody></table><p>Hook context includes <code>ctx.host</code>, the same shared services a tool gets. Persist JSON with <code>ctx.host.kv</code> and file-shaped state with <code>ctx.host.files</code>. Hooks observe; they do not own delivery surfaces.</p><h2 id="hooks-channel-events-evals-or-a-b" tabindex="-1">Hooks, channel events, evals, or A/B? <a class="header-anchor" href="#hooks-channel-events-evals-or-a-b" aria-label="Permalink to &quot;Hooks, channel events, evals, or A/B?&quot;">​</a></h2><p>All of them consume the same stream, for different jobs:</p><table tabindex="0"><thead><tr><th></th><th>Hooks</th><th>Channel <code>events</code></th><th>Evals</th><th>A/B (<code>defineAB</code>)</th></tr></thead><tbody><tr><td>Scope</td><td>every session on the agent</td><td>sessions the channel owns</td><td>one test turn</td><td>every live session; enrollment at creation, metrics on each turn</td></tr><tr><td>Job</td><td>observe: audit, metrics, mirrors, derived state</td><td>deliver: replies back to the channel&#39;s surface</td><td>assert: gates over the trajectory</td><td><code>ab.assigned</code> + fold stream → <code>onSample</code></td></tr><tr><td>Can affect the run</td><td>no</td><td>yes, it owns the surface</td><td>n/a</td><td>yes through arm instructions or <code>session.abs</code>; collection is observe-only</td></tr><tr><td>Authored at</td><td><code>agent/hooks/*.ts</code></td><td>channel config</td><td><code>evals/**/*.eval.ts</code></td><td><a href="./../ab.html"><code>agent/ab.ts</code> or <code>agent/ab/*.ts</code></a></td></tr></tbody></table><p>For GitHub merge-box checks and sticky PR banners, use <code>githubChannel({ progress: { commitStatus, banner } })</code> from <code>@cursor/july/channels/github</code>. That is the supported Autofix-style path. See <a href="./../guides/github.html#show-pr-progress">GitHub: Show PR progress</a>. Override channel <code>events</code> only when the lifecycle is custom (for example <a href="./../example-agents/approval-buddy.html">Approval Buddy</a>&#39;s never-red status from tool output). Do not use <code>defineHook</code> for those writes.</p><h2 id="patterns" tabindex="-1">Patterns <a class="header-anchor" href="#patterns" aria-label="Permalink to &quot;Patterns&quot;">​</a></h2><p>Usage metering: subscribe to <code>turn.completed</code> and forward <code>event.data.usage</code> (token counts) to your metrics system.</p><p>Failure alerting: <code>turn.failed</code> carries the message, and <code>ctx.session.id</code> points at the trace.</p><p>Derived state: <code>agent.bound</code> fires when the Cursor SDK agent id is known (<code>bc-…</code> on cloud). A PR agent can record PR → agent id from it in a hook with <code>ctx.host.kv</code>, so later webhook wakes resume the same cloud conversation. Prefer <code>ctx.host.kv</code> or <code>ctx.host.files</code> for ids that must survive hosted replace. <code>stateRoot</code> resets on replace.</p><p>Transcript export: subscribe to <code>&quot;*&quot;</code> and append to your own store. The NDJSON envelope is already ordered and replayable.</p><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><p>Continue with these pages:</p><ul><li><a href="./sessions.html">Sessions and streaming</a>: every event a hook can see</li><li><a href="./../guides/opentelemetry.html">OpenTelemetry</a>: OTLP traces and metrics from the same event stream</li><li><a href="./../deployment.html#observability">Deployment</a>: runtime logs and export paths</li><li><a href="./channels.html#events">Channels</a>: the delivery-side counterpart</li><li><a href="./../ab.html">Live A/B metrics</a>: sticky variants over the same event stream</li></ul>`,20)])])}const u=s(o,[["render",n]]);export{k as __pageData,u as default};
@@ -1,11 +0,0 @@
1
- import{_ as t,c as s,o,ag as a}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"HTTP API","description":"Every route the server mounts: sessions, approvals, deterministic tool calls, discovery, the MCP endpoint, and dev-mode dispatch.","frontmatter":{"title":"HTTP API","description":"Every route the server mounts: sessions, approvals, deterministic tool calls, discovery, the MCP endpoint, and dev-mode dispatch."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,h,c){return o(),s("div",null,[...e[0]||(e[0]=[a(`<h1 id="http-api-reference" tabindex="-1">HTTP API reference <a class="header-anchor" href="#http-api-reference" aria-label="Permalink to &quot;HTTP API reference&quot;">​</a></h1><p>Every Agent SDK host speaks the same stable HTTP API. In the default multi-agent layout each agent is namespaced under its slug (<code>/&lt;slug&gt;/v1/session</code>, <code>/&lt;slug&gt;/playground</code>), with host-level routes at the root. With <code>--mode single</code>, one agent serves the same surface unslugged (<code>/v1/*</code>).</p><p>Unless noted otherwise, routes run the agent&#39;s HTTP auth chain: the default is <code>localDevStrict()</code> (loopback only), replaced by <code>bearerAuth</code> under <code>--bearer-token</code> or <code>allowAll()</code> under <code>--allow-anonymous</code>. Session routes also require the caller to be the session&#39;s owner (<code>403</code> otherwise). Errors return JSON <code>{ ok: false, error: &quot;&lt;code&gt;&quot;, message? }</code> with a matching HTTP status.</p><h2 id="host-level-routes-multi-agent-mode" tabindex="-1">Host-level routes (multi-agent mode) <a class="header-anchor" href="#host-level-routes-multi-agent-mode" aria-label="Permalink to &quot;Host-level routes (multi-agent mode)&quot;">​</a></h2><p>These routes live at the host root, above any agent. The two index routes exist only while the playground is enabled (<code>--no-playground</code> removes them) and run no auth. The documentation site is mounted in both layouts and removed by <code>--no-docs</code>.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /</code></td><td>A web index of every mounted agent, linking to playgrounds (playground only)</td></tr><tr><td><code>GET /v1/agents</code></td><td>The JSON index of mounted agents (playground only, no auth)</td></tr><tr><td><code>GET /docs</code>, <code>GET /docs/*</code></td><td>This documentation, served as a static site (both layouts, no auth)</td></tr><tr><td><code>GET /v1/health</code></td><td>Host-level liveness, no auth; made for ALB/ECS checks</td></tr><tr><td><code>POST /v1/webhooks/github</code></td><td>Loopback-only trigger endpoint that fans a GitHub-shaped payload out to every mounted GitHub channel (used by local tooling)</td></tr></tbody></table><h2 id="start-a-session" tabindex="-1">Start a session <a class="header-anchor" href="#start-a-session" aria-label="Permalink to &quot;Start a session&quot;">​</a></h2><p><code>POST /v1/session</code> opens a durable conversation.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/session</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
2
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;content-type: application/json&#39;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
3
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;message&quot;:&quot;What can you do?&quot;}&#39;</span></span>
4
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># {&quot;ok&quot;:true,&quot;sessionId&quot;:&quot;ses_…&quot;,&quot;continuationToken&quot;:&quot;http:…&quot;,</span></span>
5
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># &quot;playgroundUrl&quot;:&quot;…?sessionId=ses_…&quot;,&quot;traceUrl&quot;:&quot;…/v1/session/ses_…/events&quot;}</span></span></code></pre></div><p>The response returns as soon as the message is accepted; follow the stream for progress. The continuation token is the follow-up credential, and <code>playgroundUrl</code> deep-links the session in the playground.</p><table tabindex="0"><thead><tr><th>Body field</th><th>Meaning</th></tr></thead><tbody><tr><td><code>message</code></td><td>Required user message</td></tr><tr><td><code>title</code></td><td>Session title</td></tr><tr><td><code>dryRun</code></td><td>Run read tools and stub write tools</td></tr><tr><td><code>workspaceFiles</code></td><td>UTF-8 files written into the session workspace</td></tr><tr><td><code>cloud</code></td><td>Per-session cloud options merged over the agent defaults</td></tr></tbody></table><h2 id="send-a-follow-up" tabindex="-1">Send a follow-up <a class="header-anchor" href="#send-a-follow-up" aria-label="Permalink to &quot;Send a follow-up&quot;">​</a></h2><p><code>POST /v1/session/:sessionId</code> continues an existing conversation.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/session/ses_…</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
6
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;content-type: application/json&#39;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
7
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;continuationToken&quot;:&quot;http:…&quot;,&quot;message&quot;:&quot;Make it shorter.&quot;}&#39;</span></span></code></pre></div><p>Works for any chat session, including ones created by custom channels. Each accepted follow-up rotates the token, and the response carries the new one. Sending to a busy session interrupts the in-flight turn, waits for it to settle, then sends.</p><p>Expect <code>409</code> on a stale token or a task session. Task sessions do not accept follow-ups. Expect <code>403</code> when the caller is not the session owner.</p><h2 id="stream-a-session" tabindex="-1">Stream a session <a class="header-anchor" href="#stream-a-session" aria-label="Permalink to &quot;Stream a session&quot;">​</a></h2><p><code>GET /v1/session/:sessionId/stream</code> is the live NDJSON feed.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;http://127.0.0.1:3000/&lt;slug&gt;/v1/session/ses_…/stream?startIndex=0&#39;</span></span></code></pre></div><p>One NDJSON event per line, from <code>startIndex</code>, then following live. The default is <code>0</code>: omitting the parameter replays the entire recorded stream before following. Pass the last index you&#39;ve seen plus one to resume without duplicates. The stream is durable and reconnectable. For the vocabulary, see <a href="./sessions.html#which-events-can-i-stream">Sessions</a>.</p><p><code>GET /v1/session/:sessionId/events</code> returns a one-shot NDJSON dump. Pass <code>?format=json</code> for <code>{ sessionId, events, playgroundUrl }</code>.</p><h2 id="stop-and-list" tabindex="-1">Stop and list <a class="header-anchor" href="#stop-and-list" aria-label="Permalink to &quot;Stop and list&quot;">​</a></h2><p><code>POST /v1/session/:sessionId/stop</code> interrupts the in-flight turn without sending a new message. <code>GET /v1/sessions</code> lists sessions owned by the calling principal. Under <code>serve --dev</code> on loopback it includes all sessions, which is how webhook and schedule sessions show up in the playground.</p><h2 id="session-cost" tabindex="-1">Session cost <a class="header-anchor" href="#session-cost" aria-label="Permalink to &quot;Session cost&quot;">​</a></h2><p><code>GET /v1/session/:sessionId/cost</code> returns the session&#39;s cost report: per-turn token usage and the engine&#39;s estimated cost, folded from <code>turn.completed</code> events. It runs the same owner check as the other session routes and returns <code>404</code> for an unknown session. The <a href="./cli.html#cost"><code>agent-sdk cost</code></a> command reports the same data.</p><h2 id="approvals" tabindex="-1">Approvals <a class="header-anchor" href="#approvals" aria-label="Permalink to &quot;Approvals&quot;">​</a></h2><p>Two routes list and resolve parked tool calls.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/session/:sessionId/approvals</code></td><td>Pending human-in-the-loop tool approvals</td></tr><tr><td><code>POST /v1/session/:sessionId/approvals/:callId</code></td><td>Resolve one: <code>{&quot;decision&quot;:&quot;approve&quot;}</code> or <code>{&quot;decision&quot;:&quot;deny&quot;}</code></td></tr></tbody></table><p>For the lifecycle, see <a href="./../guides/human-in-the-loop.html">Human-in-the-loop</a>.</p><h2 id="call-a-tool-directly" tabindex="-1">Call a tool directly <a class="header-anchor" href="#call-a-tool-directly" aria-label="Permalink to &quot;Call a tool directly&quot;">​</a></h2><p><code>POST /v1/tools/:toolName</code> runs a server tool with no model turn.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/tools/inspect_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
8
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;content-type: application/json&#39;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
9
- <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;input&quot;:{&quot;prUrl&quot;:&quot;https://github.com/acme/checkout/pull/42&quot;}}&#39;</span></span>
10
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># {&quot;ok&quot;:true,&quot;toolName&quot;:&quot;inspect_pr&quot;,&quot;callId&quot;:&quot;tool_inspect_pr_…&quot;,</span></span>
11
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># &quot;isError&quot;:false,&quot;result&quot;:{…},&quot;durationMs&quot;:12}</span></span></code></pre></div><p>It runs an authored server tool in-process: schema-validated, no model turn. An optional <code>&quot;sessionId&quot;</code> in the body runs it inside an existing session and records it on that session&#39;s stream (<code>409 session_busy</code> while a turn runs). Agent-execution tools are rejected with <code>400</code>, and unknown tools with <code>404</code> and the list of available names. For the semantics, see <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>.</p><h2 id="discovery-and-meta" tabindex="-1">Discovery and meta <a class="header-anchor" href="#discovery-and-meta" aria-label="Permalink to &quot;Discovery and meta&quot;">​</a></h2><p>Five read-only routes describe the running agent.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/info</code></td><td>The manifest snapshot: model, tools, skills, MCP connections, subagents, channels and routes (with schemas), schedules, hooks, A/B experiments, diagnostics. Always the bare project-info object; <code>agent-sdk info --json</code> wraps the same data per slug in <code>{ agents: [...] }</code></td></tr><tr><td><code>GET /v1/health</code></td><td>Per-agent liveness, no auth</td></tr><tr><td><code>GET /v1/meta</code></td><td>SPA bootstrap: agent name, dev flag, base path (no auth)</td></tr><tr><td><code>GET /v1/logs?after=N</code></td><td>Recent server log lines from the ring buffer, with a polling cursor</td></tr><tr><td><code>GET /v1/abs</code></td><td><a href="./../ab.html">Live A/B metrics</a>: per-session assignments and aggregate arm totals folded from durable event streams (<code>config</code> reports <code>maxPlaygroundSessions</code> / <code>durableSamples</code> / <code>durableSnapshots</code> from <code>agent/ab.config.ts</code>)</td></tr></tbody></table><h2 id="artifacts" tabindex="-1">Artifacts <a class="header-anchor" href="#artifacts" aria-label="Permalink to &quot;Artifacts&quot;">​</a></h2><p>Two routes read durable artifacts tagged by <code>ctx.artifacts</code> or <code>tag_artifact</code>. See <a href="./artifacts.html">Artifacts</a>.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/artifacts</code></td><td>List artifacts as <code>{ artifacts }</code>, newest-updated first. Filter with <code>?kind=</code>, <code>?sessionId=</code>, and <code>?limit=</code> (a positive integer)</td></tr><tr><td><code>GET /v1/artifacts/:id/content</code></td><td>Download one artifact&#39;s file or blob payload. Served as an attachment, never rendered inline; <code>404</code> when the artifact is unknown or carries no content</td></tr></tbody></table><p>Session ownership applies the same way as <code>GET /v1/sessions</code>: under <code>serve --dev</code> on loopback (or <code>--allow-anonymous</code>) the list spans all principals, while bearer or custom channel auth keeps strict per-principal isolation.</p><h2 id="custom-channel-routes" tabindex="-1">Custom channel routes <a class="header-anchor" href="#custom-channel-routes" aria-label="Permalink to &quot;Custom channel routes&quot;">​</a></h2><p>Authored routes mount under <code>/v1/channels/&lt;id&gt;</code> with the methods, paths, and Zod schemas the channel declared (a <code>POST /&lt;slug&gt;/v1/channels/drive</code> route, say). Bodies are validated before handlers run (<code>400</code> on schema violations), and each channel&#39;s auth chain applies. The GitHub channel verifies <code>X-Hub-Signature-256</code> when a secret is configured. See <a href="./channels.html">Channels</a>.</p><h2 id="mcp-endpoint" tabindex="-1">MCP endpoint <a class="header-anchor" href="#mcp-endpoint" aria-label="Permalink to &quot;MCP endpoint&quot;">​</a></h2><p><code>/v1/mcp</code> serves the Model Context Protocol over streamable HTTP (stateless; POST carries the protocol, and GET/DELETE return spec-compliant 405s). The tools are <code>ask</code> (delegate a message, bounded waits), <code>check</code> (poll a running session), and <code>call_tool</code> (deterministic server-tool passthrough, present when the agent has server tools). The route runs the same auth chain as the session API. See <a href="./../guides/agent-to-agent.html">Agent-to-agent</a>.</p><p><code>/v1/mcp/tools</code> is a second stateless MCP endpoint exposing only the agent&#39;s deterministic server tools. Hosted cloud turns call back into it through the URL configured by <code>serve --cloud-tools-url</code>. Unlike <code>/v1/mcp</code>, it runs the CLI-level auth chain (loopback, bearer, or anonymous), not any authored channel auth.</p><p><code>POST /v1/cursor-account/:connection/mcp</code> is the bridge for <code>defineConnection({ cursorAccount: true })</code> connections. The runtime calls it with a per-boot bearer secret; it never joins the public auth chain, and an unknown connection name returns <code>404</code>.</p><h2 id="playground-eval-routes" tabindex="-1">Playground eval routes <a class="header-anchor" href="#playground-eval-routes" aria-label="Permalink to &quot;Playground eval routes&quot;">​</a></h2><p>Always registered (including production / non-<code>--dev</code> serves). The playground Evals tab uses these:</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/dev/evals</code></td><td>List discovered eval datapoints and project config as <code>{ evals, config }</code> (<code>config</code> includes <code>maxPlaygroundRuns</code>, <code>durableRuns</code>)</td></tr><tr><td><code>GET /v1/dev/evals/runs</code></td><td>List recent run snapshots (newest first) as <code>{ runs, activeRunId? }</code> for playground rehydrate</td></tr><tr><td><code>POST /v1/dev/evals/runs</code></td><td>Start an eval run (<code>{filterIds?, tags?}</code>); <code>202</code> with a snapshot (<code>runId</code> is the Eval ID), <code>404</code> when nothing matches, <code>409</code> when one is running</td></tr><tr><td><code>GET /v1/dev/evals/runs/:runId</code></td><td>Poll a run&#39;s progress</td></tr><tr><td><code>POST /v1/dev/evals/runs/:runId/cancel</code></td><td>Cancel a running batch; <code>200</code> with snapshot, <code>404</code> unknown, <code>409</code> when not running</td></tr></tbody></table><p>Eval runs are asynchronous. Poll the run route for case progress and the final <code>completed</code> or <code>failed</code> status. Batch errors appear on the snapshot returned by the poll. Entries within <code>filterIds</code> and <code>tags</code> use OR semantics. When both fields are present, a case must match one entry from each field. Listed runs persist across restarts whenever <code>agent/storage.ts</code> provides an <code>evals</code> table or a KV core with <code>delete</code> and <code>list</code> (the table is derived — see <a href="./../storage.html">Storage</a>); otherwise they are process-memory only (capped by <code>maxPlaygroundRuns</code>).</p><h2 id="dev-mode-routes" tabindex="-1">Dev-mode routes <a class="header-anchor" href="#dev-mode-routes" aria-label="Permalink to &quot;Dev-mode routes&quot;">​</a></h2><p>These routes exist only under <code>serve --dev</code>.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>POST /v1/dev/schedules/:scheduleId</code></td><td>Dispatch a schedule by hand, exactly once, through the production path. Returns <code>{scheduleId, sessionIds}</code></td></tr><tr><td><code>GET /v1/dev/reminders</code></td><td>List reminders</td></tr><tr><td><code>POST /v1/dev/reminders/:reminderId</code></td><td>Fire a reminder by hand</td></tr></tbody></table><p>Schedules and reminders never fire automatically in dev mode. These routes are the only way they run, which keeps iteration deterministic.</p><h2 id="platform-timer-routes" tabindex="-1">Platform timer routes <a class="header-anchor" href="#platform-timer-routes" aria-label="Permalink to &quot;Platform timer routes&quot;">​</a></h2><p><code>POST /v1/internal/schedules/:scheduleId/fire</code> and <code>POST /v1/internal/reminders/:reminderId/fire</code> exist only under <code>serve --no-control-plane</code>, where the host runs no schedule or reminder clocks of its own. Cursor hosting starts engines this way and fires timed work through them. They admit only requests carrying the platform&#39;s <code>x-agent-serve-timed-work</code> marker, which the alias proxy strips from external traffic, so webhook and playground callers can never reach them.</p><h2 id="playground-assets" tabindex="-1">Playground assets <a class="header-anchor" href="#playground-assets" aria-label="Permalink to &quot;Playground assets&quot;">​</a></h2><p><code>GET /playground</code> and <code>GET /playground/assets/:file</code> serve the static SPA bundle (omitted with <code>--no-playground</code>). The playground calls the JSON API above and has no privileged surface.</p><h2 id="status-codes" tabindex="-1">Status codes <a class="header-anchor" href="#status-codes" aria-label="Permalink to &quot;Status codes&quot;">​</a></h2><p>Error responses use a small, consistent set of status codes.</p><table tabindex="0"><thead><tr><th>Code</th><th>Meaning here</th></tr></thead><tbody><tr><td><code>400</code></td><td>Schema-invalid body or query, agent-execution tool called on the host, malformed request</td></tr><tr><td><code>401</code></td><td>No auth policy admitted the request</td></tr><tr><td><code>403</code></td><td>Authenticated, but not the session owner</td></tr><tr><td><code>404</code></td><td>Unknown session, tool, schedule, reminder, or eval run; no eval datapoints match a run request</td></tr><tr><td><code>405</code></td><td>Wrong method (GET on the MCP endpoint, say)</td></tr><tr><td><code>409</code></td><td>Stale continuation token, a busy session-bound tool call, a non-followable task session, or an eval run already in progress</td></tr><tr><td><code>202</code></td><td>Accepted for background work (GitHub <code>{ task }</code> hooks, eval runs)</td></tr></tbody></table><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><p>Continue with these pages:</p><ul><li><a href="./sessions.html">Sessions and streaming</a>: the handles and events these routes traffic in</li><li><a href="./channels.html">Channels</a>: authoring your own routes</li><li><a href="./../deployment.html">Deployment</a>: auth on real hosts</li></ul>`,64)])])}const g=t(n,[["render",d]]);export{p as __pageData,g as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as s,o,ag as a}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"HTTP API","description":"Every route the server mounts: sessions, approvals, deterministic tool calls, discovery, the MCP endpoint, and dev-mode dispatch.","frontmatter":{"title":"HTTP API","description":"Every route the server mounts: sessions, approvals, deterministic tool calls, discovery, the MCP endpoint, and dev-mode dispatch."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,h,c){return o(),s("div",null,[...e[0]||(e[0]=[a("",64)])])}const g=t(n,[["render",d]]);export{p as __pageData,g as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as a,o,ag as s}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Playground","description":"The built-in web UI: chat with streaming, Try buttons and slash commands, session replay, approvals, and dev-mode dispatch.","frontmatter":{"title":"Playground","description":"The built-in web UI: chat with streaming, Try buttons and slash commands, session replay, approvals, and dev-mode dispatch."},"headers":[],"relativePath":"reference/playground.md","filePath":"reference/playground.md"}'),n={name:"reference/playground.md"};function r(l,e,d,i,c,h){return o(),a("div",null,[...e[0]||(e[0]=[s('<h1 id="playground" tabindex="-1">Playground <a class="header-anchor" href="#playground" aria-label="Permalink to &quot;Playground&quot;">​</a></h1><p>Every served agent ships with a web playground at <code>http://127.0.0.1:3000/&lt;slug&gt;/playground</code> (or <code>/playground</code> in single mode): a static SPA over the same public HTTP API, made for manual testing, demos, and reading sessions. Every call it makes runs the normal route auth chain, so anything you can do in the playground you can also do with curl.</p><h2 id="what-it-does" tabindex="-1">What it does <a class="header-anchor" href="#what-it-does" aria-label="Permalink to &quot;What it does&quot;">​</a></h2><p>The playground covers the whole manual-testing loop.</p><ul><li><strong>Chat</strong> with the agent. Text and reasoning stream live, rendered as markdown with syntax highlighting, and tool calls appear inline with their arguments, output, and error state as the <code>actions.requested</code> / <code>action.result</code> events arrive.</li><li><strong>Slash commands</strong>: custom channel routes become composer commands (a <code>drive</code> route becomes <code>/drive &lt;pr-url&gt;</code>), derived from the schemas on <code>GET /v1/info</code>, with <code>/help</code> and autocomplete.</li><li><strong>Try</strong> any channel route from the Agent surface. The modal remembers your last body per endpoint and has Copy curl, and a successful Try opens the created session.</li><li><strong>Sessions</strong>: browse every session (chat, custom-channel, schedule tasks) and replay their durable event streams. Search by session ID to filter the list, or press Enter to open an ID directly. &quot;Open trace&quot; renders any <code>events.ndjson</code> file.</li><li><strong>Approvals</strong>: parked <code>needsApproval</code> tool calls render Approve / Deny buttons.</li><li><strong>Evals</strong>: list and run filesystem evals from the browser (backed by <code>/v1/dev/evals</code>). Schedule hand-dispatch still requires <code>--dev</code>.</li><li><strong>The surface</strong>: inspect the discovered tools, skills, subagents, MCP connections, channels, and hooks.</li><li><strong>Raw NDJSON pane</strong>: flip it on to see the exact wire events.</li><li><strong>Logs tab</strong>: recent server log lines, polled from <code>GET /v1/logs</code>.</li><li><strong>A/Bs tab</strong>: per-session and aggregate <a href="./../ab.html">live A/B metrics</a> from <code>GET /v1/abs</code> (folds durable <code>ab.assigned</code> plus turn and tool events; no separate store).</li></ul><p>In multi-agent mode each agent has its own playground at <code>/&lt;slug&gt;/playground</code>, and <code>/</code> is an index of them all.</p><h2 id="share-it-beyond-localhost" tabindex="-1">Share it beyond localhost <a class="header-anchor" href="#share-it-beyond-localhost" aria-label="Permalink to &quot;Share it beyond localhost&quot;">​</a></h2><p>The default <code>localDevStrict()</code> auth admits direct loopback calls only and rejects proxy-forwarding headers, so a tunnel or LAN address won&#39;t work until you pass <code>--bearer-token &lt;secret&gt;</code> (or <code>serve(dir, { authToken })</code>). Open the playground on the remote device and paste the token into the token field in the navbar. <code>--allow-anonymous</code> is the demo-only alternative for trusted networks.</p><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><p>Continue with these pages:</p><ul><li><a href="./http-api.html">HTTP API</a>: everything the playground calls</li><li><a href="./sessions.html">Sessions and streaming</a>: the streams it renders</li><li><a href="./../guides/human-in-the-loop.html">Human-in-the-loop</a>: the approval buttons in context</li><li><a href="./../ab.html">Live A/B metrics</a>: the assignments and results in the A/Bs tab</li></ul>',11)])])}const g=t(n,[["render",r]]);export{p as __pageData,g as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as a,o,ag as s}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Playground","description":"The built-in web UI: chat with streaming, Try buttons and slash commands, session replay, approvals, and dev-mode dispatch.","frontmatter":{"title":"Playground","description":"The built-in web UI: chat with streaming, Try buttons and slash commands, session replay, approvals, and dev-mode dispatch."},"headers":[],"relativePath":"reference/playground.md","filePath":"reference/playground.md"}'),n={name:"reference/playground.md"};function r(l,e,d,i,c,h){return o(),a("div",null,[...e[0]||(e[0]=[s("",11)])])}const g=t(n,[["render",r]]);export{p as __pageData,g as default};
@@ -1,8 +0,0 @@
1
- import{_ as t,c as s,o as a,ag as o}from"./chunks/framework.BCISBCiQ.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function i(d,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o(`<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to &quot;Sessions, events, and streaming&quot;">​</a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call.</p><h2 id="what-does-a-session-contain" tabindex="-1">What does a session contain? <a class="header-anchor" href="#what-does-a-session-contain" aria-label="Permalink to &quot;What does a session contain?&quot;">​</a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>Runtime state needed to resume after a server restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="which-session-identifier-should-i-use" tabindex="-1">Which session identifier should I use? <a class="header-anchor" href="#which-session-identifier-should-i-use" aria-label="Permalink to &quot;Which session identifier should I use?&quot;">​</a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="which-session-modes-are-available" tabindex="-1">Which session modes are available? <a class="header-anchor" href="#which-session-modes-are-available" aria-label="Permalink to &quot;Which session modes are available?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don&#39;t accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="what-happens-when-i-send-a-follow-up" tabindex="-1">What happens when I send a follow-up? <a class="header-anchor" href="#what-happens-when-i-send-a-follow-up" aria-label="Permalink to &quot;What happens when I send a follow-up?&quot;">​</a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running, enqueue the follow-up, and drain queued asks into one follow-up turn when the active turn finishes (no mid-turn tool/hook inject)</td></tr></tbody></table><p>Pass <code>admission: &quot;coalesce&quot;</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>&quot;preempt&quot;</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. Interrupted turns record <code>turn.failed</code> with <code>&quot;turn interrupted&quot;</code>. This means the turn was preempted. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced nudges.</p><p>Session-bound deterministic tool calls share the same execution lock. They return <code>409 session_busy</code> while a model turn is running.</p><h2 id="which-events-can-i-stream" tabindex="-1">Which events can I stream? <a class="header-anchor" href="#which-events-can-i-stream" aria-label="Permalink to &quot;Which events can I stream?&quot;">​</a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <a href="./../ab.html#assign-sticky-variants"><code>ab.assigned</code></a>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, A/B enrollment, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>Cursor SDK agent ID and cloud conversation URL</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.queued</code>, <code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Queue position under a <a href="./agent-config.html#concurrency"><code>maxRunningTurns</code> cap</a>, then turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>action.result</code></td><td>Tool names, validated arguments, outputs, and errors</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr><tr><td>Artifacts</td><td><code>artifact.tagged</code></td><td>A durable <a href="./artifacts.html">artifact</a> was tagged for this session, by host code or <code>tag_artifact</code></td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>action.result</code> to reconstruct the tool trajectory. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts.</p><h2 id="how-do-i-stream-or-replay-session-events" tabindex="-1">How do I stream or replay session events? <a class="header-anchor" href="#how-do-i-stream-or-replay-session-events" aria-label="Permalink to &quot;How do I stream or replay session events?&quot;">​</a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;http://127.0.0.1:3000/&lt;slug&gt;/v1/session/ses_…/stream?startIndex=0&#39;</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><p>Event streams replay from disk after a server restart. Conversation state resumes from the Cursor SDK store.</p><h2 id="what-goes-into-a-local-session-workspace" tabindex="-1">What goes into a local session workspace? <a class="header-anchor" href="#what-goes-into-a-local-session-workspace" aria-label="Permalink to &quot;What goes into a local session workspace?&quot;">​</a></h2><p>The Agent SDK creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>instructions.*</code></td><td><code>AGENTS.md</code></td></tr><tr><td><code>skills/*</code></td><td><code>.cursor/skills/&lt;name&gt;/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: &quot;agent&quot;</code>)</td><td>scripts under <code>.agent-serve/tools/</code>, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>The local harness uses this workspace as its working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="where-does-the-agent-sdk-store-session-data" tabindex="-1">Where does the Agent SDK store session data? <a class="header-anchor" href="#where-does-the-agent-sdk-store-session-data" aria-label="Permalink to &quot;Where does the Agent SDK store session data?&quot;">​</a></h2><p>Local state uses one directory tree:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>&lt;project&gt;/.agent-serve/ # or &lt;stateRoot&gt;/&lt;slug&gt;/ under serve</span></span>
2
- <span class="line"><span> sessions/&lt;id&gt;/session.json # metadata: channel, mode, principal, tokens</span></span>
3
- <span class="line"><span> sessions/&lt;id&gt;/events.ndjson # the durable stream</span></span>
4
- <span class="line"><span> sessions/&lt;id&gt;/workspace/ # the harness cwd</span></span>
5
- <span class="line"><span> traces/&lt;sessionId&gt;.ndjson # written by \`run\`</span></span>
6
- <span class="line"><span> runner/ # Cursor SDK conversation store</span></span>
7
- <span class="line"><span> tool-calls/&lt;callId&gt;/ # ephemeral deterministic-call workspaces</span></span></code></pre></div><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. The <code>runner/</code> store keeps its own conversation copy until you remove it. Cloud conversations remain on the Cursor backend.</p><p>Change the root with <code>--state-root</code> or <code>stateRoot</code>. Nested git checkouts already default <code>local.cwd</code> outside the enclosing repo. See <a href="./../concepts.html#what-files-can-a-local-session-access">local session workspaces</a>.</p><h2 id="how-do-i-inspect-a-saved-event-stream" tabindex="-1">How do I inspect a saved event stream? <a class="header-anchor" href="#how-do-i-inspect-a-saved-event-stream" aria-label="Permalink to &quot;How do I inspect a saved event stream?&quot;">​</a></h2><p>Use <code>trajectory</code> with a trace or session event file:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .agent-serve/traces/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">sessionI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.ndjson</span></span>
8
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">stateRoo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/sessions/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/events.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Use <strong>Open trace</strong> in the playground for a visual view.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./../ab.html">Live A/B metrics</a></li><li><a href="./../concepts.html">How the Agent SDK works</a></li></ul>`,45)])])}const k=t(n,[["render",i]]);export{u as __pageData,k as default};
@@ -1 +0,0 @@
1
- import{_ as o,c as a,o as t,ag as l}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),s={name:"scaffolding-agents.md"};function i(r,e,n,d,c,h){return t(),a("div",null,[...e[0]||(e[0]=[l('<h1 id="scaffold-an-agent-with-cursor" tabindex="-1">Scaffold an agent with Cursor <a class="header-anchor" href="#scaffold-an-agent-with-cursor" aria-label="Permalink to &quot;Scaffold an agent with Cursor&quot;">​</a></h1><p>Turn an idea into a verified agent while Cursor guides you through each decision.</p><h2 id="what-does-the-create-agent-skill-do" tabindex="-1">What does the create-agent skill do? <a class="header-anchor" href="#what-does-the-create-agent-skill-do" aria-label="Permalink to &quot;What does the create-agent skill do?&quot;">​</a></h2><p>The bundled <a href="./../skills/create-agent/SKILL.html"><code>create-agent</code> skill</a> turns your goal into a small working project. Have Cursor read that file and follow it.</p><p>Where to find the file depends on how you got the package:</p><ul><li>Installing <code>@cursor/july</code> (<code>npm install</code>, <code>npx @cursor/july</code>, a version bump) copies every package skill into <code>~/.cursor/skills/agentsdk/</code> with <code>alwaysApply: true</code>, so Cursor injects the skill body into context instead of waiting for the model to pick it from the catalog. The <code>/</code> menu lists them as <code>/agentsdk-create-agent</code>, <code>/agentsdk-hillclimb</code>, and the rest. Re-installing overwrites those copies with the package version. Set <code>CURSOR_JULY_SKIP_SKILL_INSTALL=1</code> to skip the copy.</li><li>Installed <code>@cursor/july</code> as a dependency? The skill also ships inside the package at <code>node_modules/@cursor/july/skills/create-agent/SKILL.md</code>.</li><li>Working in the monorepo? It&#39;s at <code>packages/agent-serve/skills/create-agent/SKILL.md</code>. Run <code>agent-sdk install-skills</code> if you want the same copies in <code>~/.cursor/skills/agentsdk/</code> (the package postinstall skips the source checkout).</li></ul><p>Cursor will:</p><ul><li>Ask only for choices missing from your prompt</li><li>Recommend defaults based on what you want to build</li><li>Show you the plan and file tree before writing files</li><li>Create the agent after you confirm the plan</li><li>Run structural checks, a real turn, and a smoke eval</li></ul><p>Use this skill for a new agent. Use <a href="./guides/convert-automation.html">convert-automation</a> when the starting point is a Cursor Automation in the dashboard. Use <a href="./hillclimbing.html"><code>hillclimb</code></a> (<code>skills/hillclimb/SKILL.md</code>) when an existing agent works but needs better results.</p><h2 id="how-do-i-start-a-guided-scaffold" tabindex="-1">How do I start a guided scaffold? <a class="header-anchor" href="#how-do-i-start-a-guided-scaffold" aria-label="Permalink to &quot;How do I start a guided scaffold?&quot;">​</a></h2><p>Describe the outcome and any constraints you already know:</p><blockquote><p>Build a local weather agent for the playground. Give it one tool for current conditions and add a smoke eval. Guide me through the remaining decisions.</p></blockquote><p>More detail means fewer questions. Include a channel, runtime, model, or required integration when those choices are fixed.</p><h2 id="which-choices-will-cursor-ask-me-to-make" tabindex="-1">Which choices will Cursor ask me to make? <a class="header-anchor" href="#which-choices-will-cursor-ask-me-to-make" aria-label="Permalink to &quot;Which choices will Cursor ask me to make?&quot;">​</a></h2><p>Cursor fills gaps in two short rounds:</p><ul><li><strong>Identity:</strong> purpose, project name, and location</li><li><strong>Runtime:</strong> local or cloud</li><li><strong>Model:</strong> the default model or another Cursor model</li><li><strong>Channels:</strong> playground and HTTP, Slack, GitHub, a webhook, or a schedule</li><li><strong>MCP connections:</strong> remote or local MCP servers</li><li><strong>Capabilities:</strong> tools, skills, subagents, hooks, seed files, approvals, and evals</li></ul><p>Questions adapt to your goal. A playground chat agent won&#39;t get cloud-repository questions. A local agent won&#39;t get cloud setup questions.</p><h2 id="what-happens-before-cursor-writes-files" tabindex="-1">What happens before Cursor writes files? <a class="header-anchor" href="#what-happens-before-cursor-writes-files" aria-label="Permalink to &quot;What happens before Cursor writes files?&quot;">​</a></h2><p>Cursor shows one plan with the choices it made and the folders it will create. Choose <strong>Scaffold it</strong> to continue or <strong>Adjust something</strong> to change the plan.</p><p>No files change before you approve this step.</p><h2 id="what-will-cursor-create" tabindex="-1">What will Cursor create? <a class="header-anchor" href="#what-will-cursor-create" aria-label="Permalink to &quot;What will Cursor create?&quot;">​</a></h2><p>A first version usually includes:</p><ul><li><code>AGENTS.md</code>, <code>.gitignore</code>, <code>package.json</code>, and <code>tsconfig.json</code></li><li><code>agent/agent.ts</code> for the model and runtime</li><li><code>agent/instructions.md</code> for the always-on prompt</li><li><code>agent/hooks/memory.ts</code> for memory guidance</li><li>One or two tools under <code>agent/tools/</code></li><li>Any channels or MCP connections you selected</li><li><code>evals/evals.config.ts</code> and one smoke eval</li></ul><p>Cursor keeps the first version small. Side-effecting server tools use <code>needsApproval</code>. Deterministic setup, such as fetching a pull request, stays in host code instead of model instructions.</p><p>See <a href="./reference/project-layout.html">Project layout</a> for every supported folder.</p><h2 id="how-does-cursor-verify-the-scaffold" tabindex="-1">How does Cursor verify the scaffold? <a class="header-anchor" href="#how-does-cursor-verify-the-scaffold" aria-label="Permalink to &quot;How does Cursor verify the scaffold?&quot;">​</a></h2><p>Cursor checks the project in this order:</p><ol><li>Run <code>agent-sdk validate</code> and fix every error</li><li>Inspect the discovered surface with <code>info --json</code></li><li>Call each server tool directly with validated sample input</li><li>Run one end-to-end model turn</li><li>Run the smoke eval</li><li>Run the project&#39;s TypeScript check</li></ol><p>Validation, discovery, direct server-tool calls, and server startup work without a Cursor credential. Model turns and evals need <code>CURSOR_API_KEY</code> or a saved <code>agent-sdk login</code>.</p><h2 id="what-happens-after-the-first-agent-works" tabindex="-1">What happens after the first agent works? <a class="header-anchor" href="#what-happens-after-the-first-agent-works" aria-label="Permalink to &quot;What happens after the first agent works?&quot;">​</a></h2><p>Choose one to three fixed inputs, define what should improve, and name what must stay unchanged. Then have Cursor follow <a href="./../skills/hillclimb/SKILL.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>The hillclimb skill measures a baseline, changes one lever, runs the same inputs again, and adds an eval for each improvement you keep.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./quickstart.html">Build your first PR approver</a></li><li><a href="./guides/convert-automation.html">Convert a Cursor Automation</a></li><li><a href="./building-with-agents.html">Building agents with agents</a></li><li><a href="./evals.html">Evals</a></li><li><a href="./hillclimbing.html">Hillclimbing</a></li><li><a href="./reference/project-layout.html">Project layout</a></li></ul>',34)])])}const f=o(s,[["render",i]]);export{p as __pageData,f as default};
@@ -1 +0,0 @@
1
- import{_ as t,c as o,o as a,ag as d}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail.","frontmatter":{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail."},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md"}'),r={name:"troubleshooting.md"};function s(n,e,i,c,h,l){return a(),o("div",null,[...e[0]||(e[0]=[d('<h1 id="fix-common-agent-problems" tabindex="-1">Fix common agent problems <a class="header-anchor" href="#fix-common-agent-problems" aria-label="Permalink to &quot;Fix common agent problems&quot;">​</a></h1><p>Start with four checks, in order:</p><ol><li>Project discovery: <code>agent-sdk validate --dir .</code></li><li>Whether the serve process is running</li><li>What the playground or HTTP API shows</li><li>The session event stream (trace)</li></ol><p>Match your symptom below. Keep the commands as <code>agent-sdk</code>; see <a href="/docs/#run-the-cli">Run the CLI</a> if you still need an alias.</p><h2 id="what-if-serve-or-the-playground-looks-wrong" tabindex="-1">What if serve or the playground looks wrong? <a class="header-anchor" href="#what-if-serve-or-the-playground-looks-wrong" aria-label="Permalink to &quot;What if serve or the playground looks wrong?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>serve</code> won&#39;t start</td><td>Run <code>agent-sdk validate --dir .</code> and fix the reported errors.</td></tr><tr><td>Playground is blank or says there are no agents</td><td>The UI needs a running <code>serve</code> process. Building the playground assets alone is not enough.</td></tr><tr><td>Edits to the playground don&#39;t show up</td><td>Use <code>serve --dev</code> and open the printed playground HMR URL (often port <code>5273</code>), not only the static <code>:3000</code> URL.</td></tr><tr><td>Sessions exist on disk but the playground list is empty</td><td>The list shows sessions for the authenticated caller. In <code>--dev</code> on loopback the list is wider. Otherwise open <code>/&lt;slug&gt;/playground?sessionId=ses_…</code> or inspect <code>sessions/</code> under your state root.</td></tr><tr><td>Port 3000 or 5273 is already in use</td><td>For the default serve port, the CLI tries the next free port and prints a notice. Pass <code>--port</code> to pick one, or <code>--port 0</code> for any free port. Stop leftover Vite or webhook-forwarder processes if you need the original port.</td></tr></tbody></table><h2 id="what-if-a-model-turn-goes-wrong" tabindex="-1">What if a model turn goes wrong? <a class="header-anchor" href="#what-if-a-model-turn-goes-wrong" aria-label="Permalink to &quot;What if a model turn goes wrong?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Built-in file reads and greps fail; the turn retries for a long time</td><td>Run under Node 22.13+ (or <code>tsx</code>), never Bun. Look for <code>NGHTTP2_FRAME_SIZE_ERROR</code> in logs.</td></tr><tr><td>The turn fails immediately with an API-key error</td><td>Sign in with <code>agent-sdk login</code>, or set <code>CURSOR_API_KEY</code>. Discovery, <code>info</code>, <code>call</code>, and serve bring-up work without a key; model turns need one.</td></tr><tr><td>Replies quote rules or <code>AGENTS.md</code> from outside your agent project</td><td>The session workspace inherited parent-folder config. Nested git checkouts default <code>local.cwd</code> to <code>~/.cache/agent-serve/&lt;dir&gt;</code>. Point <code>defineAgent({ local: { cwd } })</code> at a checkout only when the agent should inherit that tree, or set <code>--state-root</code> to a clean directory (for example under <code>/tmp</code>).</td></tr><tr><td>Yellow box shows Datadog/Linear tools, but the model lists <code>GetDynamicTools</code> / IDE <code>cursor</code> tools and never calls them</td><td>Attached MCP sits behind harness meta-tools, or <code>hostOnly</code> hid the connection, or the harness cwd is still inside another checkout. Set <code>advertiseTools: true</code> for named tools on local turns. Check <code>GET /v1/info</code> <code>local.cwd</code> and <code>connections[].advertiseTools</code>.</td></tr><tr><td>Server tools, skills, or workspace seed files never appear</td><td>Server tools and sandbox seeds apply on the local runtime (cloud server tools need <code>--public-url</code> / <code>--cloud-tools-url</code>). Skills reach cloud through the Agent Store when hosting or a personal <code>CURSOR_API_KEY</code> is available; otherwise only skills already in the cloud repo. <code>validate</code> warns when this combination is present.</td></tr><tr><td><code>validate</code> and <code>run</code> succeed, but typecheck fails in CI</td><td>The CLI runs TypeScript with type-stripping only. Keep tool <code>execute</code> return types as object literals or <code>type</code> aliases, not <code>interface</code> types.</td></tr><tr><td>Login works, but turns are rejected when using custom API hosts</td><td>Point login and model traffic at the same host (<code>CURSOR_API_BASE_URL</code> and <code>CURSOR_BACKEND_URL</code>). A key from one host is rejected by the other.</td></tr></tbody></table><h2 id="what-if-the-http-api-returns-an-error" tabindex="-1">What if the HTTP API returns an error? <a class="header-anchor" href="#what-if-the-http-api-returns-an-error" aria-label="Permalink to &quot;What if the HTTP API returns an error?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>409</code> on a follow-up message</td><td>Refresh the <code>continuationToken</code> or confirm the session is a chat session. Task sessions do not accept follow-ups.</td></tr><tr><td><code>409 session_busy</code> on <code>call --session</code></td><td>Wait for the model turn to finish, or omit <code>--session</code> for a one-off call.</td></tr><tr><td><code>403</code> on stream or follow-up</td><td>Use the same auth identity that created the session. Off localhost, pass <code>--bearer-token</code> and send it on every request.</td></tr><tr><td>Works on localhost; blocked through a tunnel or LAN</td><td>Default auth allows only direct loopback callers. Share the host with <code>--bearer-token &lt;secret&gt;</code> (or authored <code>bearerAuth</code>). Use <code>--allow-anonymous</code> only on a trusted private network.</td></tr><tr><td>A channel route fails to compile with a schema type error</td><td><code>GET</code> routes need a Zod <code>querySchema</code>. <code>POST</code> / <code>PUT</code> / <code>PATCH</code> need a Zod <code>bodySchema</code>. Use <code>z.object({})</code> or <code>z.unknown()</code> for open shapes.</td></tr></tbody></table><h2 id="what-if-github-webhooks-misbehave" tabindex="-1">What if GitHub webhooks misbehave? <a class="header-anchor" href="#what-if-github-webhooks-misbehave" aria-label="Permalink to &quot;What if GitHub webhooks misbehave?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>github forward</code> returns 401 on every delivery, but the hook was created</td><td>Clear <code>GITHUB_TOKEN</code> and <code>GH_TOKEN</code> for that command. The forwarder uses your <code>gh</code> CLI login: <code>GITHUB_TOKEN= GH_TOKEN= agent-sdk github forward …</code></td></tr><tr><td><code>Hook already exists</code> when starting a forwarder</td><td>GitHub allows one forwarder per repo. Run a single <code>github forward --dir &lt;parent&gt;</code> and stop stale forwarders.</td></tr><tr><td>Deliveries rejected outside <code>--dev</code></td><td>Set <code>GITHUB_WEBHOOK_SECRET</code> on the server and on the signer. Without a secret, the channel stays loopback-only.</td></tr><tr><td>You lack repo admin and can&#39;t forward</td><td>Use <code>agent-sdk github replay &lt;pr-url&gt;</code>. It needs pull access only and posts signed test payloads.</td></tr></tbody></table><h2 id="what-if-slack-stays-quiet" tabindex="-1">What if Slack stays quiet? <a class="header-anchor" href="#what-if-slack-stays-quiet" aria-label="Permalink to &quot;What if Slack stays quiet?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Logs show <code>channel idle … missing credentials</code></td><td>Expected when tokens are missing. Run <code>agent-sdk slack create --dir &lt;agent&gt;</code> to provision the app and write the tokens, or <code>agent-sdk slack init --manual --dir &lt;agent&gt;</code> and paste the manifests at api.slack.com. Then set <code>&lt;PREFIX&gt;_SLACK_BOT_TOKEN</code> and <code>&lt;PREFIX&gt;_SLACK_APP_TOKEN</code> per agent and run <code>agent-sdk slack doctor --prefix &lt;PREFIX&gt;</code>.</td></tr><tr><td><code>slack create</code> reports the app needs admin approval</td><td>Open Slack&#39;s <strong>Request approval</strong> page (the CLI prints the link; the same URL is <strong>Send a reminder</strong> after you submit). Managed install does not file the request. Keep the CLI running, then click <strong>Retry</strong> in the dashboard after an admin approves.</td></tr><tr><td>The bot ignores ordinary channel posts</td><td>Default engagement is mentions and DMs only. Enable <code>engagement.channelPosts</code> with an allowlist, and subscribe the app to <code>message.channels</code> / <code>message.groups</code>.</td></tr><tr><td>Approve / Deny buttons do nothing</td><td>Channels that post approval cards need <code>toolApprovals: true</code>. Recreate the app with <code>slack create</code> if interactivity is off.</td></tr></tbody></table><h2 id="what-if-host-mcp-oauth-fails" tabindex="-1">What if host MCP OAuth fails? <a class="header-anchor" href="#what-if-host-mcp-oauth-fails" aria-label="Permalink to &quot;What if host MCP OAuth fails?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>must be defineConnection({ url, oauth: true })</code></td><td>The connection file needs <code>oauth: true</code>, or you passed the wrong connection name to <code>agent-sdk mcp oauth</code>.</td></tr><tr><td>Local auth works; hosted calls unauthorized</td><td>Run <code>agent-sdk mcp oauth &lt;name&gt; --store</code>, confirm names with <code>agent-sdk secrets list &lt;slug&gt;</code>, then redeploy.</td></tr><tr><td>Model asks for <code>mcp_auth</code> or IDE MCP for a privileged server</td><td>That connection is <code>hostOnly</code>. Call it from a host tool via <code>ctx.host.mcp</code>, and update instructions.</td></tr></tbody></table><p>See <a href="./guides/mcp-oauth.html">Host MCP OAuth</a> and <a href="./../skills/mcp-auth/SKILL.html"><code>skills/mcp-auth/SKILL.md</code></a>.</p><h2 id="what-if-a-secret-showed-up-in-a-terminal-transcript" tabindex="-1">What if a secret showed up in a terminal transcript? <a class="header-anchor" href="#what-if-a-secret-showed-up-in-a-terminal-transcript" aria-label="Permalink to &quot;What if a secret showed up in a terminal transcript?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>secrets set … NAME=VALUE</code> in an agent-captured terminal or shell history</td><td>Rotate the secret at the provider. Set it again with names only: <code>agent-sdk secrets set &lt;slug&gt; NAME</code> (hidden prompt) or pipe/redirect the value. <code>NAME=VALUE</code> requires <code>--from-argv</code> and still leaks into argv.</td></tr><tr><td>Alias token printed during first deploy or <code>rotate-token</code></td><td>Treat it as exposed if the transcript left your machine. Run <code>agent-sdk rotate-token &lt;slug&gt;</code>, store the new token outside agent transcripts, and update callers.</td></tr><tr><td>Someone verified a secret with <code>echo</code> / <code>printenv</code></td><td>Rotate it. Confirm presence with <code>agent-sdk secrets list &lt;slug&gt;</code> (names only), then redeploy and test the feature.</td></tr></tbody></table><h2 id="what-if-schedules-reminders-or-approvals-stall" tabindex="-1">What if schedules, reminders, or approvals stall? <a class="header-anchor" href="#what-if-schedules-reminders-or-approvals-stall" aria-label="Permalink to &quot;What if schedules, reminders, or approvals stall?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>A schedule or reminder never fires under <code>--dev</code></td><td>Dev mode does not auto-fire. Trigger with <code>POST /&lt;slug&gt;/v1/dev/schedules/&lt;id&gt;</code> or <code>POST /&lt;slug&gt;/v1/dev/reminders/&lt;id&gt;</code> (list reminders at <code>GET /v1/dev/reminders</code>).</td></tr><tr><td>A pending tool approval disappeared after restart</td><td>Parked approvals do not survive host restart. They resolve as interrupted. Run the turn again.</td></tr><tr><td>A reminder is disarmed after restart (<code>handler_lost_on_restart</code>)</td><td>Handler-form reminders live in memory. Re-arm them from the code that created them, or use prompt-form reminders.</td></tr></tbody></table><h2 id="how-do-i-read-a-session-trace" tabindex="-1">How do I read a session trace? <a class="header-anchor" href="#how-do-i-read-a-session-trace" aria-label="Permalink to &quot;How do I read a session trace?&quot;">​</a></h2><p>Look at <code>actions.requested</code> / <code>action.result</code> pairs for the tool trajectory. Count calls by tool name before blaming latency. Separate host-side work (channel <code>callTool</code>, preparation) from tools the model chose.</p><p><code>turn.failed</code> with <code>&quot;turn interrupted&quot;</code> means a follow-up or stop ended the turn on purpose.</p><p>If the model reads outside the session workspace, the prepared files don&#39;t match what the instructions expect. Fix the layout. See <a href="./hillclimbing.html">Hillclimbing</a>.</p><p><code>agent-sdk trajectory --events &lt;file&gt;</code> summarizes any saved NDJSON stream. The playground <strong>Open trace</strong> control does the same visually.</p><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><ul><li><a href="./concepts.html">Concepts</a>: the model behind these symptoms</li><li><a href="./hillclimbing.html">Hillclimbing</a>: when the agent runs but underperforms</li><li><a href="./deployment.html">Deployment</a>: auth and state on shared hosts</li></ul>',28)])])}const m=t(r,[["render",s]]);export{p as __pageData,m as default};