@cursor/july 0.1.111 → 0.1.113

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 (441) hide show
  1. package/README.md +4 -0
  2. package/dist/bin/agent-serve.js +20 -4
  3. package/dist/channels/checks.d.ts +10 -0
  4. package/dist/channels/checks.d.ts.map +1 -1
  5. package/dist/channels/github/github-channel.d.ts +29 -19
  6. package/dist/channels/github/github-channel.d.ts.map +1 -1
  7. package/dist/channels/github/github-channel.js +29 -19
  8. package/dist/channels/origin/checks.d.ts +1 -1
  9. package/dist/channels/origin/checks.d.ts.map +1 -1
  10. package/dist/channels/slack/agentic-delivery.d.ts.map +1 -1
  11. package/dist/channels/slack/agentic-delivery.js +2 -0
  12. package/dist/channels/slack/dispatch.d.ts +11 -1
  13. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  14. package/dist/channels/slack/dispatch.js +146 -39
  15. package/dist/channels/slack/placeholder.d.ts +26 -0
  16. package/dist/channels/slack/placeholder.d.ts.map +1 -1
  17. package/dist/channels/slack/placeholder.js +28 -0
  18. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  19. package/dist/channels/slack/slack-channel.js +9 -16
  20. package/dist/docs/404.html +2 -2
  21. package/dist/docs/assets/{app.Drol6mi6.js → app.CAeK13eM.js} +4 -4
  22. package/dist/docs/assets/building-with-agents.md.BBCx0AUo.js +9 -0
  23. package/dist/docs/assets/building-with-agents.md.BBCx0AUo.lean.js +1 -0
  24. package/dist/docs/assets/chunks/@localSearchIndexroot.Ck9E52Ls.js +1 -0
  25. package/dist/docs/assets/chunks/{VPLocalSearchBox.CdqoBZJX.js → VPLocalSearchBox.C9LbPHod.js} +1 -1
  26. package/dist/docs/assets/chunks/{arc.BVX3ycTn.js → arc.CmMq2zmS.js} +1 -1
  27. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CcChnMxX.js → architectureDiagram-Q4EWVU46.CCXB8Uj5.js} +1 -1
  28. package/dist/docs/assets/chunks/{baseUniq.xwtXO-yt.js → baseUniq.CyQo6eLe.js} +1 -1
  29. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.CijZ_taK.js → blockDiagram-DXYQGD6D.JYq6w91N.js} +1 -1
  30. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.0FBvwBvK.js → c4Diagram-AHTNJAMY.BRV8GPJJ.js} +1 -1
  31. package/dist/docs/assets/chunks/channel.BHiYmnZ4.js +1 -0
  32. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CELMmMDA.js → chunk-4BX2VUAB.Bv4ooYQR.js} +1 -1
  33. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.C4bhFtSm.js → chunk-4TB4RGXK.t4JtKPcj.js} +1 -1
  34. package/dist/docs/assets/chunks/{chunk-55IACEB6.ZnQ9gRRQ.js → chunk-55IACEB6.34lCHj9Y.js} +1 -1
  35. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.DPlmglG-.js → chunk-EDXVE4YY.BSwrPNrt.js} +1 -1
  36. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.BrUk8pff.js → chunk-FMBD7UC4.Beeun-R-.js} +1 -1
  37. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CcmWIncu.js → chunk-OYMX7WX6.BUUFUcJc.js} +1 -1
  38. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.D65-cs8I.js → chunk-QZHKN3VN.B2XjHzN_.js} +1 -1
  39. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.qoXZpG9F.js → chunk-YZCP3GAM.CLYG8znk.js} +1 -1
  40. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Degh8l90.js +1 -0
  41. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Degh8l90.js +1 -0
  42. package/dist/docs/assets/chunks/clone.BIywbczV.js +1 -0
  43. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.8rYtqudO.js → cose-bilkent-S5V4N54A.DVEa6fZp.js} +1 -1
  44. package/dist/docs/assets/chunks/{dagre-KV5264BT.DrRP1fOh.js → dagre-KV5264BT.C9PZQK-S.js} +1 -1
  45. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DHj_xA2_.js → diagram-5BDNPKRD.DoN0uv3Y.js} +1 -1
  46. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.Bz_6nAKj.js → diagram-G4DWMVQ6.Czv3duqx.js} +1 -1
  47. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BWA0xSW9.js → diagram-MMDJMWI5.BinJ5kWb.js} +1 -1
  48. package/dist/docs/assets/chunks/{diagram-TYMM5635.CpTJLNJI.js → diagram-TYMM5635.DW326M4K.js} +1 -1
  49. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.-7AWWSrP.js → erDiagram-SMLLAGMA.U2pR_OA7.js} +1 -1
  50. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.BTnQ742_.js → flowDiagram-DWJPFMVM.ByWJXeYK.js} +1 -1
  51. package/dist/docs/assets/chunks/framework.BNw1pucY.js +19 -0
  52. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.B5_HiiQ5.js → ganttDiagram-T4ZO3ILL.OquF0Rtg.js} +1 -1
  53. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CZcNTFZd.js → gitGraphDiagram-UUTBAWPF.Bpn01P7X.js} +1 -1
  54. package/dist/docs/assets/chunks/{graph.V2GLaab4.js → graph.CNRB6ETL.js} +1 -1
  55. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.7pZOkCCU.js → infoDiagram-42DDH7IO.CqhknMWi.js} +1 -1
  56. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DSMo3Qa3.js → ishikawaDiagram-UXIWVN3A.C6xpR2af.js} +1 -1
  57. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.BNEgWN1S.js → journeyDiagram-VCZTEJTY.Cg5f7oB3.js} +1 -1
  58. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.B-4d4tC7.js → kanban-definition-6JOO6SKY.Cx9YTwlU.js} +1 -1
  59. package/dist/docs/assets/chunks/{layout.Dvbn9nSb.js → layout.ljS-wFtK.js} +1 -1
  60. package/dist/docs/assets/chunks/{linear.D2GM4p4b.js → linear.jSxNrsFC.js} +1 -1
  61. package/dist/docs/assets/chunks/{min.DVBtLK-B.js → min.Cum8AlQw.js} +1 -1
  62. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CnJRI55x.js → mindmap-definition-QFDTVHPH.BLiysLpe.js} +1 -1
  63. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.CtoaTFlA.js → pieDiagram-DEJITSTG.BoIDyuKF.js} +1 -1
  64. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.DtT24_vN.js → quadrantDiagram-34T5L4WZ.DLkpDytR.js} +1 -1
  65. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.CjSO4o8f.js → requirementDiagram-MS252O5E.DqTVqSu2.js} +1 -1
  66. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.-wWiIVWa.js → sankeyDiagram-XADWPNL6.CG_6FF7j.js} +1 -1
  67. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.DSk8s4gX.js → sequenceDiagram-FGHM5R23.BIp9602K.js} +1 -1
  68. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.BFKAsdkN.js → stateDiagram-FHFEXIEX.COSXsD9I.js} +1 -1
  69. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.qrxrbFsX.js +1 -0
  70. package/dist/docs/assets/chunks/{theme.C0MctGaz.js → theme.CXJ7PNwy.js} +2 -2
  71. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.TUNJbAFe.js → timeline-definition-GMOUNBTQ.CXdVqkLq.js} +1 -1
  72. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.C-RGNnk4.js → vennDiagram-DHZGUBPP.CZxGuc4r.js} +1 -1
  73. package/dist/docs/assets/chunks/{wardley-RL74JXVD.g5efOWmT.js → wardley-RL74JXVD.3oVgfqQk.js} +1 -1
  74. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.DH4zt73Y.js → wardleyDiagram-NUSXRM2D.6_irCgGJ.js} +1 -1
  75. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.B-3k6bF6.js → xychartDiagram-5P7HB3ND.TRPe92m3.js} +1 -1
  76. package/dist/docs/assets/deployment.md.D2jQZuFx.js +32 -0
  77. package/dist/docs/assets/deployment.md.D2jQZuFx.lean.js +1 -0
  78. package/dist/docs/assets/evals.md.D3Y3Aixt.js +72 -0
  79. package/dist/docs/assets/evals.md.D3Y3Aixt.lean.js +1 -0
  80. package/dist/docs/assets/guides_agent-to-agent.md.CD4T5FIl.js +41 -0
  81. package/dist/docs/assets/guides_agent-to-agent.md.CD4T5FIl.lean.js +1 -0
  82. package/dist/docs/assets/guides_bitbucket.md.mpevW-VP.js +145 -0
  83. package/dist/docs/assets/guides_bitbucket.md.mpevW-VP.lean.js +1 -0
  84. package/dist/docs/assets/guides_cloud-agents.md.Cp1O3u-X.js +15 -0
  85. package/dist/docs/assets/guides_cloud-agents.md.Cp1O3u-X.lean.js +1 -0
  86. package/dist/docs/assets/guides_convert-automation.md.CqEyfP6Y.js +43 -0
  87. package/dist/docs/assets/guides_convert-automation.md.CqEyfP6Y.lean.js +1 -0
  88. package/dist/docs/assets/guides_github.md.BwpBp3ed.js +156 -0
  89. package/dist/docs/assets/guides_github.md.BwpBp3ed.lean.js +1 -0
  90. package/dist/docs/assets/guides_gitlab.md.DaEC3nMk.js +153 -0
  91. package/dist/docs/assets/guides_gitlab.md.DaEC3nMk.lean.js +1 -0
  92. package/dist/docs/assets/guides_grokbot-agents.md.CMhZNdEU.js +16 -0
  93. package/dist/docs/assets/guides_grokbot-agents.md.CMhZNdEU.lean.js +1 -0
  94. package/dist/docs/assets/guides_improve.md.Bnp4F99w.js +22 -0
  95. package/dist/docs/assets/guides_improve.md.Bnp4F99w.lean.js +1 -0
  96. package/dist/docs/assets/guides_jev.md.F5fAkkfN.js +189 -0
  97. package/dist/docs/assets/guides_jev.md.F5fAkkfN.lean.js +1 -0
  98. package/dist/docs/assets/guides_mcp-oauth.md.bSFakfCY.js +50 -0
  99. package/dist/docs/assets/guides_mcp-oauth.md.bSFakfCY.lean.js +1 -0
  100. package/dist/docs/assets/guides_opentelemetry.md.BKDxQmmd.js +35 -0
  101. package/dist/docs/assets/guides_opentelemetry.md.BKDxQmmd.lean.js +1 -0
  102. package/dist/docs/assets/guides_slack.md.Bo96y42E.js +70 -0
  103. package/dist/docs/assets/guides_slack.md.Bo96y42E.lean.js +1 -0
  104. package/dist/docs/assets/guides_webhooks.md.1A72_VEE.js +92 -0
  105. package/dist/docs/assets/guides_webhooks.md.1A72_VEE.lean.js +1 -0
  106. package/dist/docs/assets/hillclimbing.md.D4E1o5Sa.js +7 -0
  107. package/dist/docs/assets/hillclimbing.md.D4E1o5Sa.lean.js +1 -0
  108. package/dist/docs/assets/{index.md.BFVyY2KT.js → index.md.C-t81M5J.js} +2 -2
  109. package/dist/docs/assets/{index.md.BFVyY2KT.lean.js → index.md.C-t81M5J.lean.js} +1 -1
  110. package/dist/docs/assets/{quickstart.md.D3MjSZN-.js → quickstart.md.DAvVhuuU.js} +1 -1
  111. package/dist/docs/assets/{quickstart.md.D3MjSZN-.lean.js → quickstart.md.DAvVhuuU.lean.js} +1 -1
  112. package/dist/docs/assets/{reference_agent-config.md.CfVA-LZJ.js → reference_agent-config.md.DGPyw7ms.js} +1 -1
  113. package/dist/docs/assets/{reference_agent-config.md.CfVA-LZJ.lean.js → reference_agent-config.md.DGPyw7ms.lean.js} +1 -1
  114. package/dist/docs/assets/{reference_artifacts.md.Vf7qyIZ-.js → reference_artifacts.md.Bu_4HmsD.js} +1 -1
  115. package/dist/docs/assets/{reference_artifacts.md.Vf7qyIZ-.lean.js → reference_artifacts.md.Bu_4HmsD.lean.js} +1 -1
  116. package/dist/docs/assets/{reference_channels.md.icqLKcTc.js → reference_channels.md.nFWbzAic.js} +1 -1
  117. package/dist/docs/assets/{reference_channels.md.icqLKcTc.lean.js → reference_channels.md.nFWbzAic.lean.js} +1 -1
  118. package/dist/docs/assets/{reference_cli.md.B2dBL6L8.js → reference_cli.md.DLWDz9ij.js} +3 -1
  119. package/dist/docs/assets/{reference_cli.md.B2dBL6L8.lean.js → reference_cli.md.DLWDz9ij.lean.js} +1 -1
  120. package/dist/docs/assets/{reference_connections.md.Cb3U_c8n.js → reference_connections.md.Je9dMsdd.js} +2 -2
  121. package/dist/docs/assets/{reference_connections.md.Cb3U_c8n.lean.js → reference_connections.md.Je9dMsdd.lean.js} +1 -1
  122. package/dist/docs/assets/reference_evals.md.DNJzM_yf.js +57 -0
  123. package/dist/docs/assets/reference_evals.md.DNJzM_yf.lean.js +1 -0
  124. package/dist/docs/assets/reference_extensions.md.Cv5aLCz_.js +58 -0
  125. package/dist/docs/assets/reference_extensions.md.Cv5aLCz_.lean.js +1 -0
  126. package/dist/docs/assets/{reference_hooks.md.CZuynAxj.js → reference_hooks.md.B7uzNENk.js} +2 -2
  127. package/dist/docs/assets/{reference_hooks.md.CZuynAxj.lean.js → reference_hooks.md.B7uzNENk.lean.js} +1 -1
  128. package/dist/docs/assets/{reference_http-api.md.DTKcYE6L.js → reference_http-api.md.CduHavZ2.js} +1 -1
  129. package/dist/docs/assets/{reference_http-api.md.DTKcYE6L.lean.js → reference_http-api.md.CduHavZ2.lean.js} +1 -1
  130. package/dist/docs/assets/{reference_instructions.md.D7gkckK-.js → reference_instructions.md.CU1My5My.js} +1 -1
  131. package/dist/docs/assets/{reference_instructions.md.D7gkckK-.lean.js → reference_instructions.md.CU1My5My.lean.js} +1 -1
  132. package/dist/docs/assets/{reference_playground.md.D2YExv5K.js → reference_playground.md.Ch2d0Iqi.js} +1 -1
  133. package/dist/docs/assets/{reference_playground.md.D2YExv5K.lean.js → reference_playground.md.Ch2d0Iqi.lean.js} +1 -1
  134. package/dist/docs/assets/{reference_project-layout.md.DPxbUJyt.js → reference_project-layout.md.BGhgpy9V.js} +1 -1
  135. package/dist/docs/assets/{reference_project-layout.md.DPxbUJyt.lean.js → reference_project-layout.md.BGhgpy9V.lean.js} +1 -1
  136. package/dist/docs/assets/{reference_prompt.md.BQ5uAv1F.js → reference_prompt.md.Ccp0R53H.js} +1 -1
  137. package/dist/docs/assets/{reference_prompt.md.BQ5uAv1F.lean.js → reference_prompt.md.Ccp0R53H.lean.js} +1 -1
  138. package/dist/docs/assets/{reference_schedules.md.BasfZWO-.js → reference_schedules.md.B2Nm6FaD.js} +1 -1
  139. package/dist/docs/assets/{reference_schedules.md.BasfZWO-.lean.js → reference_schedules.md.B2Nm6FaD.lean.js} +1 -1
  140. package/dist/docs/assets/{reference_sessions.md.YKvIsWAx.js → reference_sessions.md.1_6Vyv7x.js} +1 -1
  141. package/dist/docs/assets/{reference_sessions.md.YKvIsWAx.lean.js → reference_sessions.md.1_6Vyv7x.lean.js} +1 -1
  142. package/dist/docs/assets/{reference_skills.md.rNgpsGd0.js → reference_skills.md.DjQkRefx.js} +1 -1
  143. package/dist/docs/assets/{reference_skills.md.rNgpsGd0.lean.js → reference_skills.md.DjQkRefx.lean.js} +1 -1
  144. package/dist/docs/assets/{reference_subagents.md.e5qitjJt.js → reference_subagents.md.Dl16gcBj.js} +2 -2
  145. package/dist/docs/assets/{reference_subagents.md.e5qitjJt.lean.js → reference_subagents.md.Dl16gcBj.lean.js} +1 -1
  146. package/dist/docs/assets/{reference_tools.md.BdCO2aHZ.js → reference_tools.md.B1dH1lpa.js} +3 -3
  147. package/dist/docs/assets/{reference_tools.md.BdCO2aHZ.lean.js → reference_tools.md.B1dH1lpa.lean.js} +1 -1
  148. package/dist/docs/assets/{templates_agentic-owners.md.Da_AGDlH.js → templates_agentic-owners.md.9M575F5C.js} +1 -1
  149. package/dist/docs/assets/{templates_agentic-owners.md.Da_AGDlH.lean.js → templates_agentic-owners.md.9M575F5C.lean.js} +1 -1
  150. package/dist/docs/assets/{templates_pr-autofixer.md.DqxocIGh.js → templates_pr-autofixer.md.ws0DDXDy.js} +1 -1
  151. package/dist/docs/assets/{templates_pr-autofixer.md.DqxocIGh.lean.js → templates_pr-autofixer.md.ws0DDXDy.lean.js} +1 -1
  152. package/dist/docs/assets/{templates_security-reviewer.md.Bhnvd8VE.js → templates_security-reviewer.md.KEFYXzfK.js} +1 -1
  153. package/dist/docs/assets/{templates_security-reviewer.md.Bhnvd8VE.lean.js → templates_security-reviewer.md.KEFYXzfK.lean.js} +1 -1
  154. package/dist/docs/assets/templates_thermo-quality-review.md.VNJ_mohX.js +3 -0
  155. package/dist/docs/assets/templates_thermo-quality-review.md.VNJ_mohX.lean.js +1 -0
  156. package/dist/docs/assets/templates_thermo-review.md.Hi3zWOkP.js +3 -0
  157. package/dist/docs/assets/templates_thermo-review.md.Hi3zWOkP.lean.js +1 -0
  158. package/dist/docs/assets/{templates_triage.md.BdBWO9Ic.js → templates_triage.md.CVGe_FG6.js} +1 -1
  159. package/dist/docs/assets/{templates_triage.md.BdBWO9Ic.lean.js → templates_triage.md.CVGe_FG6.lean.js} +1 -1
  160. package/dist/docs/assets/troubleshooting.md.mnfFG2Em.js +1 -0
  161. package/dist/docs/assets/troubleshooting.md.mnfFG2Em.lean.js +1 -0
  162. package/dist/docs/building-with-agents.html +44 -48
  163. package/dist/docs/building-with-agents.md +94 -82
  164. package/dist/docs/deployment.html +59 -78
  165. package/dist/docs/deployment.md +117 -363
  166. package/dist/docs/evals.html +85 -224
  167. package/dist/docs/evals.md +149 -673
  168. package/dist/docs/guides/agent-to-agent.html +74 -47
  169. package/dist/docs/guides/agent-to-agent.md +128 -46
  170. package/dist/docs/guides/bitbucket.html +179 -44
  171. package/dist/docs/guides/bitbucket.md +249 -48
  172. package/dist/docs/guides/cloud-agents.html +46 -40
  173. package/dist/docs/guides/cloud-agents.md +119 -66
  174. package/dist/docs/guides/convert-automation.html +80 -49
  175. package/dist/docs/guides/convert-automation.md +156 -147
  176. package/dist/docs/guides/github.html +184 -92
  177. package/dist/docs/guides/github.md +260 -245
  178. package/dist/docs/guides/gitlab.html +184 -45
  179. package/dist/docs/guides/gitlab.md +249 -50
  180. package/dist/docs/guides/grokbot-agents.html +48 -41
  181. package/dist/docs/guides/grokbot-agents.md +99 -53
  182. package/dist/docs/guides/improve.html +48 -40
  183. package/dist/docs/guides/improve.md +111 -58
  184. package/dist/docs/guides/jev.html +248 -0
  185. package/dist/docs/guides/jev.md +348 -0
  186. package/dist/docs/guides/mcp-oauth.html +74 -52
  187. package/dist/docs/guides/mcp-oauth.md +111 -121
  188. package/dist/docs/guides/opentelemetry.html +63 -54
  189. package/dist/docs/guides/opentelemetry.md +96 -165
  190. package/dist/docs/guides/slack.html +83 -59
  191. package/dist/docs/guides/slack.md +157 -227
  192. package/dist/docs/guides/webhooks.html +97 -230
  193. package/dist/docs/guides/webhooks.md +154 -385
  194. package/dist/docs/hashmap.json +1 -1
  195. package/dist/docs/hillclimbing.html +44 -38
  196. package/dist/docs/hillclimbing.md +101 -55
  197. package/dist/docs/index.html +38 -38
  198. package/dist/docs/index.md +2 -0
  199. package/dist/docs/llms-full.txt +3490 -3146
  200. package/dist/docs/llms.txt +22 -18
  201. package/dist/docs/quickstart.html +37 -37
  202. package/dist/docs/reference/agent-config.html +37 -37
  203. package/dist/docs/reference/artifacts.html +38 -38
  204. package/dist/docs/reference/channels.html +37 -37
  205. package/dist/docs/reference/cli.html +39 -37
  206. package/dist/docs/reference/cli.md +2 -0
  207. package/dist/docs/reference/connections.html +38 -38
  208. package/dist/docs/reference/connections.md +1 -1
  209. package/dist/docs/reference/evals.html +116 -0
  210. package/dist/docs/reference/evals.md +293 -0
  211. package/dist/docs/reference/extensions.html +80 -84
  212. package/dist/docs/reference/extensions.md +131 -202
  213. package/dist/docs/reference/hooks.html +39 -39
  214. package/dist/docs/reference/hooks.md +34 -34
  215. package/dist/docs/reference/http-api.html +37 -37
  216. package/dist/docs/reference/instructions.html +37 -37
  217. package/dist/docs/reference/playground.html +37 -37
  218. package/dist/docs/reference/project-layout.html +37 -37
  219. package/dist/docs/reference/prompt.html +37 -37
  220. package/dist/docs/reference/schedules.html +37 -37
  221. package/dist/docs/reference/sessions.html +37 -37
  222. package/dist/docs/reference/skills.html +37 -37
  223. package/dist/docs/reference/subagents.html +38 -38
  224. package/dist/docs/reference/subagents.md +1 -1
  225. package/dist/docs/reference/tools.html +38 -38
  226. package/dist/docs/reference/tools.md +4 -0
  227. package/dist/docs/templates/agentic-owners.html +38 -38
  228. package/dist/docs/templates/pr-autofixer.html +37 -37
  229. package/dist/docs/templates/security-reviewer.html +38 -38
  230. package/dist/docs/templates/thermo-quality-review.html +62 -0
  231. package/dist/docs/templates/thermo-quality-review.md +75 -0
  232. package/dist/docs/templates/thermo-review.html +62 -0
  233. package/dist/docs/templates/thermo-review.md +74 -0
  234. package/dist/docs/templates/triage.html +37 -37
  235. package/dist/docs/troubleshooting.html +38 -38
  236. package/dist/docs/troubleshooting.md +97 -66
  237. package/dist/extensions/cursor-cloud-agents/skills/handoff.md +3 -7
  238. package/dist/extensions/improve/extension.d.ts +3 -1
  239. package/dist/extensions/improve/extension.d.ts.map +1 -1
  240. package/dist/extensions/improve/extension.js +4 -2
  241. package/dist/extensions/improve/skills/yourself.js +1 -1
  242. package/dist/extensions/jev/extension.d.ts +43 -0
  243. package/dist/extensions/jev/extension.d.ts.map +1 -0
  244. package/dist/extensions/jev/extension.js +47 -0
  245. package/dist/extensions/jev/lib/evaluate.d.ts +101 -0
  246. package/dist/extensions/jev/lib/evaluate.d.ts.map +1 -0
  247. package/dist/extensions/jev/lib/evaluate.js +167 -0
  248. package/dist/extensions/jev/skills/gated-write.md +25 -0
  249. package/dist/extensions/jev/skills/questions.md +33 -0
  250. package/dist/extensions/jev/tools/evaluate.d.ts +4 -0
  251. package/dist/extensions/jev/tools/evaluate.d.ts.map +1 -0
  252. package/dist/extensions/jev/tools/evaluate.js +88 -0
  253. package/dist/extensions.d.ts +1 -1
  254. package/dist/extensions.d.ts.map +1 -1
  255. package/dist/extensions.js +2 -0
  256. package/dist/filesystem.d.ts +46 -2
  257. package/dist/filesystem.d.ts.map +1 -1
  258. package/dist/filesystem.js +149 -102
  259. package/dist/index.d.ts +2 -2
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +1 -1
  262. package/dist/internal/advertise-tools.d.ts.map +1 -1
  263. package/dist/internal/advertise-tools.js +6 -0
  264. package/dist/internal/cli-ax.d.ts +6 -0
  265. package/dist/internal/cli-ax.d.ts.map +1 -1
  266. package/dist/internal/cli-ax.js +72 -14
  267. package/dist/internal/continuation-identity.d.ts.map +1 -1
  268. package/dist/internal/continuation-identity.js +1 -0
  269. package/dist/internal/cursor-agent-template.d.ts +1 -1
  270. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  271. package/dist/internal/cursor-agent-template.js +2 -0
  272. package/dist/internal/discovery/connections.d.ts.map +1 -1
  273. package/dist/internal/discovery/connections.js +18 -0
  274. package/dist/internal/discovery/extensions.d.ts.map +1 -1
  275. package/dist/internal/discovery/extensions.js +8 -4
  276. package/dist/internal/discovery/info.d.ts.map +1 -1
  277. package/dist/internal/discovery/info.js +1 -0
  278. package/dist/internal/filesystem/tools.d.ts.map +1 -1
  279. package/dist/internal/filesystem/tools.js +2 -2
  280. package/dist/internal/filesystem/walk.d.ts +7 -4
  281. package/dist/internal/filesystem/walk.d.ts.map +1 -1
  282. package/dist/internal/filesystem/walk.js +34 -11
  283. package/dist/internal/hosted-admission-adapter.d.ts +3 -0
  284. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  285. package/dist/internal/hosted-delivery-protocol.d.ts +20 -0
  286. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  287. package/dist/internal/hosted-delivery-protocol.js +51 -1
  288. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  289. package/dist/internal/hosted-delivery.js +23 -25
  290. package/dist/internal/hosted-execution-diag.d.ts +12 -4
  291. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  292. package/dist/internal/hosted-execution-diag.js +26 -4
  293. package/dist/internal/hosted-execution-flush.d.ts +1 -0
  294. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  295. package/dist/internal/hosted-execution-flush.js +4 -2
  296. package/dist/internal/init-project.d.ts.map +1 -1
  297. package/dist/internal/init-project.js +4 -0
  298. package/dist/internal/server.d.ts.map +1 -1
  299. package/dist/internal/server.js +111 -48
  300. package/dist/internal/session-engine.d.ts +4 -1
  301. package/dist/internal/session-engine.d.ts.map +1 -1
  302. package/dist/internal/session-engine.js +39 -9
  303. package/dist/internal/skill-catalog.d.ts +28 -0
  304. package/dist/internal/skill-catalog.d.ts.map +1 -0
  305. package/dist/internal/skill-catalog.js +44 -0
  306. package/dist/playground/assets/index-DSMAewbx.css +1 -0
  307. package/dist/playground/assets/index-De_lpFxE.js +67 -0
  308. package/dist/playground/index.html +2 -2
  309. package/dist/types.d.ts +32 -3
  310. package/dist/types.d.ts.map +1 -1
  311. package/docs/README.md +2 -0
  312. package/docs/building-with-agents.md +96 -84
  313. package/docs/deployment.md +118 -364
  314. package/docs/evals.md +149 -673
  315. package/docs/guides/agent-to-agent.md +130 -48
  316. package/docs/guides/bitbucket.md +250 -49
  317. package/docs/guides/cloud-agents.md +119 -67
  318. package/docs/guides/convert-automation.md +157 -148
  319. package/docs/guides/github.md +261 -246
  320. package/docs/guides/gitlab.md +250 -51
  321. package/docs/guides/grokbot-agents.md +100 -55
  322. package/docs/guides/improve.md +112 -59
  323. package/docs/guides/jev.md +353 -0
  324. package/docs/guides/mcp-oauth.md +112 -122
  325. package/docs/guides/opentelemetry.md +97 -166
  326. package/docs/guides/slack.md +158 -228
  327. package/docs/guides/webhooks.md +155 -386
  328. package/docs/hillclimbing.md +102 -56
  329. package/docs/reference/cli.md +2 -0
  330. package/docs/reference/connections.md +1 -1
  331. package/docs/reference/evals.md +298 -0
  332. package/docs/reference/extensions.md +132 -203
  333. package/docs/reference/hooks.md +34 -34
  334. package/docs/reference/subagents.md +1 -1
  335. package/docs/reference/tools.md +4 -0
  336. package/docs/templates/thermo-quality-review.md +80 -0
  337. package/docs/templates/thermo-review.md +79 -0
  338. package/docs/troubleshooting.md +98 -67
  339. package/package.json +8 -1
  340. package/skills/github/SKILL.md +21 -13
  341. package/src/bin/agent-serve.ts +24 -3
  342. package/src/channels/checks.ts +8 -0
  343. package/src/channels/github/github-channel.ts +29 -19
  344. package/src/channels/origin/checks.ts +3 -1
  345. package/src/channels/slack/agentic-delivery.ts +2 -0
  346. package/src/channels/slack/dispatch.ts +131 -4
  347. package/src/channels/slack/placeholder.ts +51 -0
  348. package/src/channels/slack/slack-channel.ts +9 -2
  349. package/src/extensions/cursor-cloud-agents/skills/handoff.md +3 -7
  350. package/src/extensions/improve/extension.ts +4 -2
  351. package/src/extensions/improve/skills/yourself.ts +1 -1
  352. package/src/extensions/jev/extension.ts +95 -0
  353. package/src/extensions/jev/lib/evaluate.ts +289 -0
  354. package/src/extensions/jev/skills/gated-write.md +25 -0
  355. package/src/extensions/jev/skills/questions.md +33 -0
  356. package/src/extensions/jev/tools/evaluate.ts +90 -0
  357. package/src/extensions.ts +2 -0
  358. package/src/filesystem.ts +168 -65
  359. package/src/index.ts +3 -0
  360. package/src/internal/advertise-tools.ts +6 -0
  361. package/src/internal/cli-ax.ts +88 -15
  362. package/src/internal/continuation-identity.ts +1 -0
  363. package/src/internal/cursor-agent-template.ts +2 -0
  364. package/src/internal/discovery/connections.ts +21 -0
  365. package/src/internal/discovery/extensions.ts +12 -4
  366. package/src/internal/discovery/info.ts +1 -0
  367. package/src/internal/filesystem/tools.ts +2 -0
  368. package/src/internal/filesystem/walk.ts +60 -15
  369. package/src/internal/hosted-admission-adapter.ts +3 -0
  370. package/src/internal/hosted-delivery-protocol.ts +82 -1
  371. package/src/internal/hosted-delivery.ts +23 -0
  372. package/src/internal/hosted-execution-diag.ts +33 -4
  373. package/src/internal/hosted-execution-flush.ts +4 -0
  374. package/src/internal/init-project.ts +4 -0
  375. package/src/internal/server.ts +130 -53
  376. package/src/internal/session-engine.ts +46 -8
  377. package/src/internal/skill-catalog.ts +69 -0
  378. package/src/types.ts +33 -3
  379. package/templates/thermo-quality-review/README.md +35 -0
  380. package/templates/thermo-quality-review/agent/agent.ts +8 -0
  381. package/templates/thermo-quality-review/agent/channels/github.ts +42 -0
  382. package/templates/thermo-quality-review/agent/instructions.md +43 -0
  383. package/templates/thermo-quality-review/agent/tools/post_findings.ts +70 -0
  384. package/templates/thermo-quality-review/evals/evals.config.ts +5 -0
  385. package/templates/thermo-quality-review/evals/review.eval.ts +62 -0
  386. package/templates/thermo-quality-review/package.json +18 -0
  387. package/templates/thermo-quality-review/tsconfig.json +12 -0
  388. package/templates/thermo-review/README.md +35 -0
  389. package/templates/thermo-review/agent/agent.ts +8 -0
  390. package/templates/thermo-review/agent/channels/github.ts +42 -0
  391. package/templates/thermo-review/agent/instructions.md +40 -0
  392. package/templates/thermo-review/agent/tools/post_findings.ts +70 -0
  393. package/templates/thermo-review/evals/evals.config.ts +5 -0
  394. package/templates/thermo-review/evals/review.eval.ts +53 -0
  395. package/templates/thermo-review/package.json +18 -0
  396. package/templates/thermo-review/tsconfig.json +12 -0
  397. package/dist/docs/assets/building-with-agents.md.CEGVXkmO.js +0 -13
  398. package/dist/docs/assets/building-with-agents.md.CEGVXkmO.lean.js +0 -1
  399. package/dist/docs/assets/chunks/@localSearchIndexroot.DtXk1hy-.js +0 -1
  400. package/dist/docs/assets/chunks/channel.Bkv1N-gK.js +0 -1
  401. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CZDco1o8.js +0 -1
  402. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CZDco1o8.js +0 -1
  403. package/dist/docs/assets/chunks/clone.YSt_40_s.js +0 -1
  404. package/dist/docs/assets/chunks/framework.dypDpWZ3.js +0 -19
  405. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.C4CLm481.js +0 -1
  406. package/dist/docs/assets/deployment.md.Dm4Qo3hp.js +0 -51
  407. package/dist/docs/assets/deployment.md.Dm4Qo3hp.lean.js +0 -1
  408. package/dist/docs/assets/evals.md.BLDRt5LH.js +0 -211
  409. package/dist/docs/assets/evals.md.BLDRt5LH.lean.js +0 -1
  410. package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.js +0 -14
  411. package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.lean.js +0 -1
  412. package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.js +0 -10
  413. package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.lean.js +0 -1
  414. package/dist/docs/assets/guides_cloud-agents.md.lSE_l7lH.js +0 -9
  415. package/dist/docs/assets/guides_cloud-agents.md.lSE_l7lH.lean.js +0 -1
  416. package/dist/docs/assets/guides_convert-automation.md.Ck6Cr68A.js +0 -12
  417. package/dist/docs/assets/guides_convert-automation.md.Ck6Cr68A.lean.js +0 -1
  418. package/dist/docs/assets/guides_github.md.D6ER29dG.js +0 -64
  419. package/dist/docs/assets/guides_github.md.D6ER29dG.lean.js +0 -1
  420. package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.js +0 -14
  421. package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.lean.js +0 -1
  422. package/dist/docs/assets/guides_grokbot-agents.md.WBZIOvkz.js +0 -9
  423. package/dist/docs/assets/guides_grokbot-agents.md.WBZIOvkz.lean.js +0 -1
  424. package/dist/docs/assets/guides_improve.md.BKaDuKKK.js +0 -14
  425. package/dist/docs/assets/guides_improve.md.BKaDuKKK.lean.js +0 -1
  426. package/dist/docs/assets/guides_mcp-oauth.md.DMNMpXtO.js +0 -28
  427. package/dist/docs/assets/guides_mcp-oauth.md.DMNMpXtO.lean.js +0 -1
  428. package/dist/docs/assets/guides_opentelemetry.md._CRfDyzH.js +0 -26
  429. package/dist/docs/assets/guides_opentelemetry.md._CRfDyzH.lean.js +0 -1
  430. package/dist/docs/assets/guides_slack.md.DdT8rmsj.js +0 -46
  431. package/dist/docs/assets/guides_slack.md.DdT8rmsj.lean.js +0 -1
  432. package/dist/docs/assets/guides_webhooks.md.aQW10HRe.js +0 -225
  433. package/dist/docs/assets/guides_webhooks.md.aQW10HRe.lean.js +0 -1
  434. package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.js +0 -1
  435. package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.lean.js +0 -1
  436. package/dist/docs/assets/reference_extensions.md.wlFD3cUR.js +0 -62
  437. package/dist/docs/assets/reference_extensions.md.wlFD3cUR.lean.js +0 -1
  438. package/dist/docs/assets/troubleshooting.md.BcgNoYtJ.js +0 -1
  439. package/dist/docs/assets/troubleshooting.md.BcgNoYtJ.lean.js +0 -1
  440. package/dist/playground/assets/index-BLlKgZtI.css +0 -1
  441. package/dist/playground/assets/index-CDS5p9sR.js +0 -67
@@ -1,4 +1,4 @@
1
- import{_ as e,c as a,o as i,a3 as t}from"./chunks/framework.dypDpWZ3.js";const c=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"}'),n={name:"reference/hooks.md"};function h(o,s,l,d,r,p){return i(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="hooks" tabindex="-1">Hooks <a class="header-anchor" href="#hooks" aria-label="Permalink to &quot;Hooks&quot;">​</a></h1><p>A hook subscribes to the session event stream and runs a side effect after each event is recorded: an audit line, a metric, a copy of the transcript in your own store, or derived state for later turns. Hooks run in the serving process for every session of the agent, on local and cloud runtime turns alike.</p><p>Hooks observe. They can&#39;t change the turn, the prompt, or the reply, and a handler that throws is logged and skipped. Treat the event as read-only; later subscribers see the same object. That makes hooks safe to add to a production agent, and the wrong tool for anything that must happen before the model runs or must fail a turn; see <a href="#when-not-to-use-a-hook">When not to use a hook</a>.</p><p><code>defineHook</code> is unrelated to <a href="https://cursor.com/docs/agent/hooks" target="_blank" rel="noreferrer">Cursor Agent hooks</a>, the <code>.cursor/hooks.json</code> scripts that can observe, block, or modify the agent loop. Those still run inside a local session workspace.</p><h2 id="author-a-hook" tabindex="-1">Author a hook <a class="header-anchor" href="#author-a-hook" aria-label="Permalink to &quot;Author a hook&quot;">​</a></h2><p>Author <code>agent/hooks/&lt;name&gt;.ts</code> with <code>defineHook</code> from <code>@cursor/july/hooks</code>. This one meters tokens:</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:#6A737D;--shiki-dark:#6A737D;">// agent/hooks/usage.ts</span></span>
1
+ import{_ as e,c as a,o as i,a3 as t}from"./chunks/framework.BNw1pucY.js";const c=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"}'),n={name:"reference/hooks.md"};function h(o,s,l,d,r,p){return i(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="hooks" tabindex="-1">Hooks <a class="header-anchor" href="#hooks" aria-label="Permalink to &quot;Hooks&quot;">​</a></h1><p>A hook subscribes to the session event stream and runs a side effect after each event is recorded: an audit line, a metric, a copy of the transcript in your own store, or derived state for later turns. Hooks run in the serving process for every session of the agent, on local and cloud runtime turns alike.</p><p>Hooks observe. They can&#39;t change the turn, the prompt, or the reply, and a handler that throws is logged and skipped. Treat the event as read-only; later subscribers see the same object. That makes hooks safe to add to a production agent, and the wrong tool for anything that must happen before the model runs or must fail a turn; see <a href="#when-not-to-use-a-hook">When not to use a hook</a>.</p><p><code>defineHook</code> is unrelated to <a href="https://cursor.com/docs/agent/hooks" target="_blank" rel="noreferrer">Cursor Agent hooks</a>, the <code>.cursor/hooks.json</code> scripts that can observe, block, or modify the agent loop. Those still run inside a local session workspace.</p><h2 id="author-a-hook" tabindex="-1">Author a hook <a class="header-anchor" href="#author-a-hook" aria-label="Permalink to &quot;Author a hook&quot;">​</a></h2><p>Author <code>agent/hooks/&lt;name&gt;.ts</code> with <code>defineHook</code> from <code>@cursor/july/hooks</code>. This one meters tokens:</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:#6A737D;--shiki-dark:#6A737D;">// agent/hooks/usage.ts</span></span>
2
2
  <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>
3
3
  <span class="line"></span>
4
4
  <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>
@@ -15,7 +15,7 @@ import{_ as e,c as a,o as i,a3 as t}from"./chunks/framework.dypDpWZ3.js";const c
15
15
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.otel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">increment</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;acme.turn.failed&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, { channel: ctx.channel.id });</span></span>
16
16
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
17
17
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
18
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Any module under <code>agent/hooks/</code>, subfolders included, is a hook named by its path without the extension: <code>agent/hooks/audit/usage.ts</code> is <code>audit/usage</code>. <code>*.test.ts</code> and <code>*.spec.ts</code> files are skipped. The default export must be <code>defineHook(...)</code>, names can&#39;t contain <code>__</code>, and an empty <code>events</code> map skips the hook with a warning; <code>agent-sdk validate</code> reports all three. An extension mounts its hooks as <code>&lt;ns&gt;__&lt;name&gt;</code>, and <code>disableHook()</code> removes one (<a href="./extensions.html#adjust-a-mounted-extension">Adjust a mounted extension</a>).</p><p><code>agent-sdk init</code> scaffolds <code>agent/hooks/memory.ts</code>, which exports <code>memoryHook()</code> from <code>@cursor/july/memory</code> and journals every turn for later sessions to read. Delete the file to opt out.</p><h2 id="events-and-payloads" tabindex="-1">Events and payloads <a class="header-anchor" href="#events-and-payloads" aria-label="Permalink to &quot;Events and payloads&quot;">​</a></h2><p>Keys are event types from the <a href="./sessions.html#which-events-can-i-stream">event vocabulary</a>, or <code>&quot;*&quot;</code> for every event. A typed key narrows <code>event.data</code>; a <code>&quot;*&quot;</code> handler receives the union, so switch on <code>event.type</code>. Every event carries the stream envelope <code>{ type, index, sessionId, turnId?, at, data }</code>, with <code>turnId</code> set on turn-scoped events.</p><p>The payloads hooks read most often:</p><table tabindex="0"><thead><tr><th>Event</th><th><code>event.data</code></th></tr></thead><tbody><tr><td><code>message.received</code></td><td><code>{ text }</code></td></tr><tr><td><code>turn.completed</code></td><td><code>{ result?, usage?, cost? }</code>. <code>usage</code> has <code>inputTokens</code>, <code>outputTokens</code>, <code>cacheReadTokens</code>, <code>cacheWriteTokens</code>, and optional <code>reasoningTokens</code>. <code>cost</code> has <code>totalUsd</code> and the <code>model</code> it was priced against</td></tr><tr><td><code>turn.failed</code></td><td><code>{ message }</code></td></tr><tr><td><code>actions.requested</code></td><td><code>{ calls: [{ callId, toolName, args? }] }</code>. A call with <code>parentCallId</code> belongs to a subagent</td></tr><tr><td><code>action.result</code></td><td><code>{ callId, toolName, output?, isError, stubbed? }</code>. <code>stubbed</code> means a dry-run session answered a write without running it</td></tr></tbody></table><p>The types are <code>SessionEvent</code>, <code>SessionEventType</code>, and <code>HookContext</code>, exported from <code>@cursor/july</code>.</p><h2 id="handler-context" tabindex="-1">Handler context <a class="header-anchor" href="#handler-context" aria-label="Permalink to &quot;Handler context&quot;">​</a></h2><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: <code>id</code>, <code>channelId</code>, <code>mode</code> (<code>chat</code> or <code>task</code>), <code>purpose</code> (<code>live</code> or <code>eval</code>), <code>auth</code>, plus <code>title</code> and <code>sdkAgentId</code> when set</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>. The token is <code>null</code> when the session can&#39;t take follow-ups</td></tr><tr><td><code>ctx.host.kv</code></td><td>Durable JSON, shared by every session of the agent; the storage backend decides whether it survives a hosted replace. Prefix keys with <code>ctx.session.id</code> for per-session state</td></tr><tr><td><code>ctx.host.files</code></td><td>Durable files, bound to this session. Pass <code>{ scope: &quot;deployment&quot; }</code> for agent-wide files</td></tr><tr><td><code>ctx.host.otel</code></td><td>Counters, histograms, and tags, attributed to this session</td></tr><tr><td><code>ctx.host.mcp</code>, <code>ctx.host.github</code>, <code>ctx.host.slack</code></td><td>The same shared clients tools get</td></tr><tr><td><code>ctx.host.reminders</code></td><td>Per-session <a href="./schedules.html">reminders</a>, the same API tools get</td></tr><tr><td><code>ctx.artifacts</code></td><td>Session-bound <a href="./artifacts.html">artifacts</a> facade: <code>tag</code> fills in <code>sessionId</code> and <code>turnId</code></td></tr><tr><td><code>ctx.stateRoot</code></td><td>Absolute path of the local state root. It resets when a hosted deployment is replaced; keep derived state in <code>kv</code> or <code>files</code></td></tr></tbody></table><h2 id="when-hooks-run" tabindex="-1">When hooks run <a class="header-anchor" href="#when-hooks-run" aria-label="Permalink to &quot;When hooks run&quot;">​</a></h2><p>A hook runs after the event is durably recorded. It never delays the model turn and never sees an event that wasn&#39;t recorded.</p><p>Within one session, events dispatch in order, one at a time: the channel&#39;s <code>events</code> handlers first, then each hook in discovery order. Sessions don&#39;t wait on each other.</p><p>Two consequences:</p><ul><li>A slow handler holds up the next event&#39;s handlers for that session, not the model. Keep handlers short and queue anything slow.</li><li>Hooks fire for eval sessions too. Check <code>ctx.session.purpose === &quot;eval&quot;</code> before metering or paging.</li></ul><p>Each event reaches a hook at most once. A restart doesn&#39;t replay the log into hooks, so a mirror needs no dedupe, and the event log rather than the hook&#39;s copy is the source of truth.</p><h2 id="hooks-channel-events-or-evals" tabindex="-1">Hooks, channel events, or evals? <a class="header-anchor" href="#hooks-channel-events-or-evals" aria-label="Permalink to &quot;Hooks, channel events, or evals?&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></tr></thead><tbody><tr><td>Scope</td><td>every session of the agent</td><td>sessions the channel owns</td><td>one test 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></tr><tr><td>Context</td><td><code>ctx.host</code>, <code>ctx.artifacts</code>, session info</td><td><code>channel.state</code>, <code>setContinuationToken</code>, <code>ctx.host</code>, session info</td><td>the <code>t</code> assertion helpers</td></tr><tr><td>Can affect the run</td><td>no</td><td>yes, it owns the surface</td><td>n/a</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></tr></tbody></table><h2 id="when-not-to-use-a-hook" tabindex="-1">When not to use a hook <a class="header-anchor" href="#when-not-to-use-a-hook" aria-label="Permalink to &quot;When not to use a hook&quot;">​</a></h2><table tabindex="0"><thead><tr><th>You want to</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model runs</td><td>The channel&#39;s <code>send</code> message and <code>workspaceFiles</code>, <code>instructions.md</code>, skills, or <code>sandbox/workspace/</code> seed files</td></tr><tr><td>Reply on Slack, comment on a PR, or post any other delivery</td><td>The channel&#39;s <code>events</code> map, or the Slack and GitHub packs</td></tr><tr><td>Show PR progress (merge-box check, sticky banner)</td><td><code>githubChannel({ progress: { commitStatus, banner } })</code>; see <a href="./../guides/github.html#show-pr-progress">Show PR progress</a></td></tr><tr><td>Block, approve, or rewrite a tool call</td><td><a href="./tools.html#gate-a-tool-on-human-approval"><code>needsApproval</code></a> on the tool</td></tr><tr><td>Act on the final assistant text, reject it for a same-turn repair, or fail a bad turn</td><td><code>defineResult</code></td></tr><tr><td>Gate a change on behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><h2 id="patterns" tabindex="-1">Patterns <a class="header-anchor" href="#patterns" aria-label="Permalink to &quot;Patterns&quot;">​</a></h2><p>Usage metering is the <a href="#author-a-hook">authoring example</a>. Three more:</p><h3 id="alert-on-failure" tabindex="-1">Alert on failure <a class="header-anchor" href="#alert-on-failure" aria-label="Permalink to &quot;Alert on failure&quot;">​</a></h3><p><code>turn.failed</code> carries the message, and <code>ctx.session.id</code> points at the trace. Skip interrupted turns; those are preemptions, not failures. Read secrets inside the handler: hosted deployments bind them after the process starts, so a module-scope read stays empty. Give the call a timeout, since a stalled request holds up later handlers on that session.</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:#6A737D;--shiki-dark:#6A737D;">// agent/hooks/page-on-failure.ts</span></span>
18
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Any module under <code>agent/hooks/</code>, subfolders included, is a hook named by its path without the extension: <code>agent/hooks/audit/usage.ts</code> is <code>audit/usage</code>. <code>*.test.ts</code> and <code>*.spec.ts</code> files are skipped. The default export must be <code>defineHook(...)</code>, names can&#39;t contain <code>__</code>, and an empty <code>events</code> map skips the hook with a warning; <code>agent-sdk validate</code> reports all three. An extension mounts its hooks as <code>&lt;ns&gt;__&lt;name&gt;</code>, and <code>disableHook()</code> removes one (<a href="./extensions.html#adjust-a-mounted-extension">Adjust a mounted extension</a>).</p><p><code>agent-sdk init</code> scaffolds <code>agent/hooks/memory.ts</code>, which exports <code>memoryHook()</code> from <code>@cursor/july/memory</code> and journals every turn for later sessions to read. Delete the file to opt out.</p><h2 id="events-and-payloads" tabindex="-1">Events and payloads <a class="header-anchor" href="#events-and-payloads" aria-label="Permalink to &quot;Events and payloads&quot;">​</a></h2><p>Keys are event types from the <a href="./sessions.html#which-events-can-i-stream">event vocabulary</a>, or <code>&quot;*&quot;</code> for every event. A typed key narrows <code>event.data</code>; a <code>&quot;*&quot;</code> handler receives the union, so switch on <code>event.type</code>. Every event carries the stream envelope <code>{ type, index, sessionId, turnId?, at, data }</code>, with <code>turnId</code> set on turn-scoped events.</p><p>The payloads hooks read most often:</p><table tabindex="0"><thead><tr><th>Event</th><th><code>event.data</code></th></tr></thead><tbody><tr><td><code>message.received</code></td><td><code>{ text }</code></td></tr><tr><td><code>turn.completed</code></td><td><code>{ result?, usage?, cost? }</code>. <code>usage</code> has <code>inputTokens</code>, <code>outputTokens</code>, <code>cacheReadTokens</code>, <code>cacheWriteTokens</code>, and optional <code>reasoningTokens</code>. <code>cost</code> has <code>totalUsd</code> and the <code>model</code> it was priced against</td></tr><tr><td><code>turn.failed</code></td><td><code>{ message }</code></td></tr><tr><td><code>actions.requested</code></td><td><code>{ calls: [{ callId, toolName, args? }] }</code>. A call with <code>parentCallId</code> belongs to a subagent</td></tr><tr><td><code>action.result</code></td><td><code>{ callId, toolName, output?, isError, stubbed? }</code>. <code>stubbed</code> means a dry-run session answered a write without running it</td></tr></tbody></table><p>The types are <code>SessionEvent</code>, <code>SessionEventType</code>, and <code>HookContext</code>, exported from <code>@cursor/july</code>.</p><h2 id="handler-context" tabindex="-1">Handler context <a class="header-anchor" href="#handler-context" aria-label="Permalink to &quot;Handler context&quot;">​</a></h2><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: <code>id</code>, <code>channelId</code>, <code>mode</code> (<code>chat</code> or <code>task</code>), <code>purpose</code> (<code>live</code> or <code>eval</code>), <code>auth</code>, plus <code>title</code> and <code>sdkAgentId</code> when set</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>. The token is <code>null</code> when the session can&#39;t take follow-ups</td></tr><tr><td><code>ctx.host.kv</code></td><td>Durable JSON, shared by every session of the agent; the storage backend decides whether it survives a hosted replace. Prefix keys with <code>ctx.session.id</code> for per-session state</td></tr><tr><td><code>ctx.host.files</code></td><td>Durable files, bound to this session. Pass <code>{ scope: &quot;deployment&quot; }</code> for agent-wide files</td></tr><tr><td><code>ctx.host.otel</code></td><td>Counters, histograms, and tags, attributed to this session</td></tr><tr><td><code>ctx.host.mcp</code>, <code>ctx.host.github</code>, <code>ctx.host.slack</code></td><td>The same shared clients tools get</td></tr><tr><td><code>ctx.host.reminders</code></td><td>Per-session <a href="./schedules.html">reminders</a>, the same API tools get</td></tr><tr><td><code>ctx.artifacts</code></td><td>Session-bound <a href="./artifacts.html">artifacts</a> facade: <code>tag</code> fills in <code>sessionId</code> and <code>turnId</code></td></tr><tr><td><code>ctx.stateRoot</code></td><td>Absolute path of the local state root. It resets when a hosted deployment is replaced; keep derived state in <code>kv</code> or <code>files</code></td></tr></tbody></table><h2 id="when-hooks-run" tabindex="-1">When hooks run <a class="header-anchor" href="#when-hooks-run" aria-label="Permalink to &quot;When hooks run&quot;">​</a></h2><p>A hook runs after the event is durably recorded. It never delays the model turn and never sees an event that wasn&#39;t recorded.</p><p>Within one session, events dispatch in order, one at a time: the channel&#39;s <code>events</code> handlers first, then each hook in discovery order. Sessions don&#39;t wait on each other.</p><p>Two consequences:</p><ul><li>A slow handler holds up the next event&#39;s handlers for that session, not the model. Keep handlers short and queue anything slow.</li><li>Hooks fire for eval sessions too. Check <code>ctx.session.purpose === &quot;eval&quot;</code> before metering or paging.</li></ul><p>Each event reaches a hook at most once. A restart doesn&#39;t replay the log into hooks, so a mirror needs no dedupe, and the event log rather than the hook&#39;s copy is the source of truth.</p><h2 id="hooks-channel-events-or-evals" tabindex="-1">Hooks, channel events, or evals? <a class="header-anchor" href="#hooks-channel-events-or-evals" aria-label="Permalink to &quot;Hooks, channel events, or evals?&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></tr></thead><tbody><tr><td>Scope</td><td>every session of the agent</td><td>sessions the channel owns</td><td>one test 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></tr><tr><td>Context</td><td><code>ctx.host</code>, <code>ctx.artifacts</code>, session info</td><td><code>channel.state</code>, <code>setContinuationToken</code>, <code>ctx.host</code>, session info</td><td>the <code>t</code> assertion helpers</td></tr><tr><td>Can affect the run</td><td>no</td><td>yes, it owns the surface</td><td>n/a</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></tr></tbody></table><h2 id="when-not-to-use-a-hook" tabindex="-1">When not to use a hook <a class="header-anchor" href="#when-not-to-use-a-hook" aria-label="Permalink to &quot;When not to use a hook&quot;">​</a></h2><table tabindex="0"><thead><tr><th>You want to</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model runs</td><td>The channel&#39;s <code>send</code> message and <code>workspaceFiles</code>, <code>instructions.md</code>, skills, or <code>sandbox/workspace/</code> seed files</td></tr><tr><td>Reply on Slack, comment on a PR, or post any other delivery</td><td>The channel&#39;s <code>events</code> map, or the Slack and GitHub packs</td></tr><tr><td>Show PR progress (merge-box check, sticky banner)</td><td><code>githubChannel({ progress: { commitStatus, banner } })</code>; see the <a href="./../templates/pr-autofixer.html">PR autofixer</a></td></tr><tr><td>Block, approve, or rewrite a tool call</td><td><a href="./tools.html#gate-a-tool-on-human-approval"><code>needsApproval</code></a> on the tool</td></tr><tr><td>Act on the final assistant text, reject it for a same-turn repair, or fail a bad turn</td><td><code>defineResult</code></td></tr><tr><td>Gate a change on behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><h2 id="patterns" tabindex="-1">Patterns <a class="header-anchor" href="#patterns" aria-label="Permalink to &quot;Patterns&quot;">​</a></h2><p>Usage metering is the <a href="#author-a-hook">authoring example</a>. Three more:</p><h3 id="alert-on-failure" tabindex="-1">Alert on failure <a class="header-anchor" href="#alert-on-failure" aria-label="Permalink to &quot;Alert on failure&quot;">​</a></h3><p><code>turn.failed</code> carries the message, and <code>ctx.session.id</code> points at the trace. Skip interrupted turns; those are preemptions, not failures. Read secrets inside the handler: hosted deployments bind them after the process starts, so a module-scope read stays empty. Give the call a timeout, since a stalled request holds up later handlers on that session.</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:#6A737D;--shiki-dark:#6A737D;">// agent/hooks/page-on-failure.ts</span></span>
19
19
  <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>
20
20
  <span class="line"></span>
21
21
  <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>
@@ -1 +1 @@
1
- import{_ as e,c as a,o as i,a3 as t}from"./chunks/framework.dypDpWZ3.js";const c=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"}'),n={name:"reference/hooks.md"};function h(o,s,l,d,r,p){return i(),a("div",null,[...s[0]||(s[0]=[t("",45)])])}const E=e(n,[["render",h]]);export{c as __pageData,E as default};
1
+ import{_ as e,c as a,o as i,a3 as t}from"./chunks/framework.BNw1pucY.js";const c=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"}'),n={name:"reference/hooks.md"};function h(o,s,l,d,r,p){return i(),a("div",null,[...s[0]||(s[0]=[t("",45)])])}const E=e(n,[["render",h]]);export{c as __pageData,E as default};
@@ -1,4 +1,4 @@
1
- import{_ as t,c as s,o,a3 as a}from"./chunks/framework.dypDpWZ3.js";const p=JSON.parse('{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use.","frontmatter":{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,c,h){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>Agent SDK hosts expose the same public HTTP surface. 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</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>
1
+ import{_ as t,c as s,o,a3 as a}from"./chunks/framework.BNw1pucY.js";const p=JSON.parse('{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use.","frontmatter":{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,c,h){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>Agent SDK hosts expose the same public HTTP surface. 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</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
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
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
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>
@@ -1 +1 @@
1
- import{_ as t,c as s,o,a3 as a}from"./chunks/framework.dypDpWZ3.js";const p=JSON.parse('{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use.","frontmatter":{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,c,h){return o(),s("div",null,[...e[0]||(e[0]=[a("",62)])])}const k=t(n,[["render",d]]);export{p as __pageData,k as default};
1
+ import{_ as t,c as s,o,a3 as a}from"./chunks/framework.BNw1pucY.js";const p=JSON.parse('{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use.","frontmatter":{"title":"HTTP API","description":"Public session, discovery, and channel routes callers use."},"headers":[],"relativePath":"reference/http-api.md","filePath":"reference/http-api.md"}'),n={name:"reference/http-api.md"};function d(i,e,r,l,c,h){return o(),s("div",null,[...e[0]||(e[0]=[a("",62)])])}const k=t(n,[["render",d]]);export{p as __pageData,k as default};
@@ -1,4 +1,4 @@
1
- import{_ as t,c as e,o as i,a3 as a}from"./chunks/framework.dypDpWZ3.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,l,p,d){return i(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="instructions" tabindex="-1">Instructions <a class="header-anchor" href="#instructions" aria-label="Permalink to &quot;Instructions&quot;">​</a></h1><p><code>agent/instructions.md</code> is the always-on system prompt. It&#39;s the one piece of prose the model sees on every turn. It&#39;s required on the root agent; subagents may inline <code>instructions</code> in their <code>agent.ts</code> instead.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to &quot;Authoring forms&quot;">​</a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/instructions.md</code></td><td>Plain Markdown for most agents.</td></tr><tr><td><code>agent/instructions.ts</code></td><td>Generated prompts. Default-export <code>defineInstructions({ markdown })</code> or a plain string.</td></tr><tr><td><code>agent/instructions/</code> directory</td><td>A long prompt split across files, composed in filename order.</td></tr></tbody></table><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:#6A737D;--shiki-dark:#6A737D;">// agent/instructions.ts</span></span>
1
+ import{_ as t,c as e,o as i,a3 as a}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,l,p,d){return i(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="instructions" tabindex="-1">Instructions <a class="header-anchor" href="#instructions" aria-label="Permalink to &quot;Instructions&quot;">​</a></h1><p><code>agent/instructions.md</code> is the always-on system prompt. It&#39;s the one piece of prose the model sees on every turn. It&#39;s required on the root agent; subagents may inline <code>instructions</code> in their <code>agent.ts</code> instead.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to &quot;Authoring forms&quot;">​</a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/instructions.md</code></td><td>Plain Markdown for most agents.</td></tr><tr><td><code>agent/instructions.ts</code></td><td>Generated prompts. Default-export <code>defineInstructions({ markdown })</code> or a plain string.</td></tr><tr><td><code>agent/instructions/</code> directory</td><td>A long prompt split across files, composed in filename order.</td></tr></tbody></table><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:#6A737D;--shiki-dark:#6A737D;">// agent/instructions.ts</span></span>
2
2
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineInstructions } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
3
3
  <span class="line"></span>
4
4
  <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;"> defineInstructions</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
@@ -1 +1 @@
1
- import{_ as t,c as e,o as i,a3 as a}from"./chunks/framework.dypDpWZ3.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,l,p,d){return i(),e("div",null,[...s[0]||(s[0]=[a("",17)])])}const u=t(n,[["render",o]]);export{k as __pageData,u as default};
1
+ import{_ as t,c as e,o as i,a3 as a}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,l,p,d){return i(),e("div",null,[...s[0]||(s[0]=[a("",17)])])}const u=t(n,[["render",o]]);export{k as __pageData,u as default};
@@ -1 +1 @@
1
- import{_ as t,c as o,o as a,a3 as n}from"./chunks/framework.dypDpWZ3.js";const u=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"}'),s={name:"reference/playground.md"};function r(l,e,d,i,c,h){return a(),o("div",null,[...e[0]||(e[0]=[n('<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). Anything you can do there 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>Use the playground to chat, try channel routes, and inspect sessions.</p><ul><li><strong>Chat</strong> with the agent. Text and reasoning stream live, and tool calls appear inline with their arguments, output, and error state.</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>), 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 the sessions you own (chat, custom-channel, schedule tasks) and replay their event streams. In <code>--dev</code> on loopback, or with <code>--allow-anonymous</code>, the list includes every principal. Search by session ID to filter the list, or press Enter to open an ID directly. &quot;Open trace&quot; renders a saved event stream.</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>Custom tool chips</strong>: drop <code>agent/playground/tools/&lt;toolName&gt;.tsx</code> to change how that tool renders. Chips compile from the agent tree; an <a href="./extensions.html">extension</a> cannot contribute them.</li><li><strong>Raw events pane</strong>: flip it on to inspect the event stream.</li><li><strong>Logs tab</strong>: recent server log lines, polled from <code>GET /v1/logs</code>.</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>: the HTTP surface the playground uses</li><li><a href="./sessions.html">Sessions and streaming</a>: the streams it renders</li><li><a href="./tools.html#gate-a-tool-on-human-approval">Gate a tool on human approval</a>: the approval buttons in context</li></ul>',11)])])}const g=t(s,[["render",r]]);export{u as __pageData,g as default};
1
+ import{_ as t,c as o,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=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"}'),s={name:"reference/playground.md"};function r(l,e,d,i,c,h){return a(),o("div",null,[...e[0]||(e[0]=[n('<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). Anything you can do there 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>Use the playground to chat, try channel routes, and inspect sessions.</p><ul><li><strong>Chat</strong> with the agent. Text and reasoning stream live, and tool calls appear inline with their arguments, output, and error state.</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>), 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 the sessions you own (chat, custom-channel, schedule tasks) and replay their event streams. In <code>--dev</code> on loopback, or with <code>--allow-anonymous</code>, the list includes every principal. Search by session ID to filter the list, or press Enter to open an ID directly. &quot;Open trace&quot; renders a saved event stream.</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>Custom tool chips</strong>: drop <code>agent/playground/tools/&lt;toolName&gt;.tsx</code> to change how that tool renders. Chips compile from the agent tree; an <a href="./extensions.html">extension</a> cannot contribute them.</li><li><strong>Raw events pane</strong>: flip it on to inspect the event stream.</li><li><strong>Logs tab</strong>: recent server log lines, polled from <code>GET /v1/logs</code>.</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>: the HTTP surface the playground uses</li><li><a href="./sessions.html">Sessions and streaming</a>: the streams it renders</li><li><a href="./tools.html#gate-a-tool-on-human-approval">Gate a tool on human approval</a>: the approval buttons in context</li></ul>',11)])])}const g=t(s,[["render",r]]);export{u as __pageData,g as default};
@@ -1 +1 @@
1
- import{_ as t,c as o,o as a,a3 as n}from"./chunks/framework.dypDpWZ3.js";const u=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"}'),s={name:"reference/playground.md"};function r(l,e,d,i,c,h){return a(),o("div",null,[...e[0]||(e[0]=[n("",11)])])}const g=t(s,[["render",r]]);export{u as __pageData,g as default};
1
+ import{_ as t,c as o,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=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"}'),s={name:"reference/playground.md"};function r(l,e,d,i,c,h){return a(),o("div",null,[...e[0]||(e[0]=[n("",11)])])}const g=t(s,[["render",r]]);export{u as __pageData,g as default};
@@ -1,4 +1,4 @@
1
- import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.dypDpWZ3.js";const g=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function n(r,e,i,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o(`<h1 id="project-layout" tabindex="-1">Project layout <a class="header-anchor" href="#project-layout" aria-label="Permalink to &quot;Project layout&quot;">​</a></h1><p>The Agent SDK builds an agent by walking the filesystem under <code>agent/</code>. Each folder has a defined purpose. The path a file lands in determines how the Agent SDK loads it.</p><h2 id="folder-structure" tabindex="-1">Folder structure <a class="header-anchor" href="#folder-structure" aria-label="Permalink to &quot;Folder structure&quot;">​</a></h2><p>For the capabilities below, identity comes from the path.</p><table tabindex="0"><thead><tr><th>Path</th><th>Resolves to</th></tr></thead><tbody><tr><td><code>agent/tools/approve_pr.ts</code></td><td>tool <code>approve_pr</code></td></tr><tr><td><code>agent/mcp-connections/linear.ts</code></td><td>MCP connection <code>linear</code> (model + host)</td></tr><tr><td><code>agent/host-connections/anytool.ts</code></td><td>Host MCP connection <code>anytool</code> (host + <code>mcp oauth</code> only)</td></tr><tr><td><code>agent/skills/pr-review.md</code></td><td>skill <code>pr-review</code></td></tr><tr><td><code>agent/subagents/reviewer/</code></td><td>subagent <code>reviewer</code></td></tr><tr><td><code>agent/extensions/ci.ts</code></td><td>extension mount <code>ci</code>; its contributions become <code>ci__&lt;name&gt;</code></td></tr><tr><td><code>agent/extensions/notion.ts</code></td><td>Cursor plugin mount <code>notion</code> (<code>cursorPlugin</code>); its skills, agents, and MCP servers become <code>notion__&lt;name&gt;</code></td></tr><tr><td><code>agent/channels/drive.ts</code></td><td>channel <code>drive</code>, routes under <code>/v1/channels/drive</code></td></tr></tbody></table><p>The root agent takes its name from <code>package.json</code> <code>name</code>, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match <code>[A-Za-z0-9][A-Za-z0-9_-]*</code> (and not the reserved <code>v1</code>, <code>playground</code>, or <code>docs</code> segments).</p><h2 id="project-overview" tabindex="-1">Project overview <a class="header-anchor" href="#project-overview" aria-label="Permalink to &quot;Project overview&quot;">​</a></h2><p>Most projects start with 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>my-agent/</span></span>
1
+ import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.BNw1pucY.js";const g=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function n(r,e,i,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o(`<h1 id="project-layout" tabindex="-1">Project layout <a class="header-anchor" href="#project-layout" aria-label="Permalink to &quot;Project layout&quot;">​</a></h1><p>The Agent SDK builds an agent by walking the filesystem under <code>agent/</code>. Each folder has a defined purpose. The path a file lands in determines how the Agent SDK loads it.</p><h2 id="folder-structure" tabindex="-1">Folder structure <a class="header-anchor" href="#folder-structure" aria-label="Permalink to &quot;Folder structure&quot;">​</a></h2><p>For the capabilities below, identity comes from the path.</p><table tabindex="0"><thead><tr><th>Path</th><th>Resolves to</th></tr></thead><tbody><tr><td><code>agent/tools/approve_pr.ts</code></td><td>tool <code>approve_pr</code></td></tr><tr><td><code>agent/mcp-connections/linear.ts</code></td><td>MCP connection <code>linear</code> (model + host)</td></tr><tr><td><code>agent/host-connections/anytool.ts</code></td><td>Host MCP connection <code>anytool</code> (host + <code>mcp oauth</code> only)</td></tr><tr><td><code>agent/skills/pr-review.md</code></td><td>skill <code>pr-review</code></td></tr><tr><td><code>agent/subagents/reviewer/</code></td><td>subagent <code>reviewer</code></td></tr><tr><td><code>agent/extensions/ci.ts</code></td><td>extension mount <code>ci</code>; its contributions become <code>ci__&lt;name&gt;</code></td></tr><tr><td><code>agent/extensions/notion.ts</code></td><td>Cursor plugin mount <code>notion</code> (<code>cursorPlugin</code>); its skills, agents, and MCP servers become <code>notion__&lt;name&gt;</code></td></tr><tr><td><code>agent/channels/drive.ts</code></td><td>channel <code>drive</code>, routes under <code>/v1/channels/drive</code></td></tr></tbody></table><p>The root agent takes its name from <code>package.json</code> <code>name</code>, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match <code>[A-Za-z0-9][A-Za-z0-9_-]*</code> (and not the reserved <code>v1</code>, <code>playground</code>, or <code>docs</code> segments).</p><h2 id="project-overview" tabindex="-1">Project overview <a class="header-anchor" href="#project-overview" aria-label="Permalink to &quot;Project overview&quot;">​</a></h2><p>Most projects start with 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>my-agent/</span></span>
2
2
  <span class="line"><span>├── package.json</span></span>
3
3
  <span class="line"><span>├── agent/</span></span>
4
4
  <span class="line"><span>│ ├── agent.ts # runtime config (model, runtime, cloud/local)</span></span>
@@ -1 +1 @@
1
- import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.dypDpWZ3.js";const g=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function n(r,e,i,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o("",20)])])}const u=t(d,[["render",n]]);export{g as __pageData,u as default};
1
+ import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.BNw1pucY.js";const g=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function n(r,e,i,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o("",20)])])}const u=t(d,[["render",n]]);export{g as __pageData,u as default};
@@ -1 +1 @@
1
- import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.dypDpWZ3.js";const c=JSON.parse('{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors.","frontmatter":{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors."},"headers":[],"relativePath":"reference/prompt.md","filePath":"reference/prompt.md"}'),n={name:"reference/prompt.md"};function p(r,s,l,o,h,d){return t(),i("div",null,[...s[0]||(s[0]=[a('<h1 id="prompt" tabindex="-1"><code>prompt</code> <a class="header-anchor" href="#prompt" aria-label="Permalink to &quot;`prompt`&quot;">​</a></h1><p>Authoring helper for long strings that live next to indented TypeScript: tool descriptions, reminder <code>prompt</code> fields, GitHub channel <code>context</code>, and error messages.</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;"> { prompt } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// or: import { prompt } from &quot;@cursor/july/prompt&quot;;</span></span></code></pre></div><h2 id="prompt-1" tabindex="-1"><code>prompt\\</code>…`` <a class="header-anchor" href="#prompt-1" aria-label="Permalink to &quot;`prompt\\`…\\``&quot;">​</a></h2><p>Returns a single dedented string. Common leading whitespace is stripped; a leading newline after the opening backtick is dropped so the usual multiline form stays readable in source.</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;">throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prompt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> It is outside business hours (Mon–Fri 9am–5pm ET).</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Use request_author_approval, or pass approval=human_request.</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>Blank lines inside the body are preserved. Relative indentation after the common prefix is kept (handy for nested bullet lists).</p><p>When interpolating multi-line values (for example a list of services), give those lines the same indent as the <code>prompt</code> body so dedent stays consistent.</p><h2 id="prompt-lines" tabindex="-1"><code>prompt.lines\\</code>…`` <a class="header-anchor" href="#prompt-lines" aria-label="Permalink to &quot;`prompt.lines\\`…\\``&quot;">​</a></h2><p>Same dedent rules, but returns <code>string[]</code>, one entry per line. Use this where an API wants separate lines (for example GitHub channel <code>context</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:#6F42C1;--shiki-dark:#B392F0;">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: prompt.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lines</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Merged PR detected: ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">pr</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">url</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">} by ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">author</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}.</span></span>\n<span class="line"></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Call plan_deploy, then follow its nextStep.</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span></code></pre></div>',11)])])}const m=e(n,[["render",p]]);export{c as __pageData,m as default};
1
+ import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors.","frontmatter":{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors."},"headers":[],"relativePath":"reference/prompt.md","filePath":"reference/prompt.md"}'),n={name:"reference/prompt.md"};function p(r,s,l,o,h,d){return t(),i("div",null,[...s[0]||(s[0]=[a('<h1 id="prompt" tabindex="-1"><code>prompt</code> <a class="header-anchor" href="#prompt" aria-label="Permalink to &quot;`prompt`&quot;">​</a></h1><p>Authoring helper for long strings that live next to indented TypeScript: tool descriptions, reminder <code>prompt</code> fields, GitHub channel <code>context</code>, and error messages.</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;"> { prompt } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// or: import { prompt } from &quot;@cursor/july/prompt&quot;;</span></span></code></pre></div><h2 id="prompt-1" tabindex="-1"><code>prompt\\</code>…`` <a class="header-anchor" href="#prompt-1" aria-label="Permalink to &quot;`prompt\\`…\\``&quot;">​</a></h2><p>Returns a single dedented string. Common leading whitespace is stripped; a leading newline after the opening backtick is dropped so the usual multiline form stays readable in source.</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;">throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prompt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> It is outside business hours (Mon–Fri 9am–5pm ET).</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Use request_author_approval, or pass approval=human_request.</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>Blank lines inside the body are preserved. Relative indentation after the common prefix is kept (handy for nested bullet lists).</p><p>When interpolating multi-line values (for example a list of services), give those lines the same indent as the <code>prompt</code> body so dedent stays consistent.</p><h2 id="prompt-lines" tabindex="-1"><code>prompt.lines\\</code>…`` <a class="header-anchor" href="#prompt-lines" aria-label="Permalink to &quot;`prompt.lines\\`…\\``&quot;">​</a></h2><p>Same dedent rules, but returns <code>string[]</code>, one entry per line. Use this where an API wants separate lines (for example GitHub channel <code>context</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:#6F42C1;--shiki-dark:#B392F0;">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: prompt.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lines</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Merged PR detected: ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">pr</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">url</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">} by ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">author</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}.</span></span>\n<span class="line"></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> Call plan_deploy, then follow its nextStep.</span></span>\n<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`</span></span></code></pre></div>',11)])])}const m=e(n,[["render",p]]);export{c as __pageData,m as default};
@@ -1 +1 @@
1
- import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.dypDpWZ3.js";const c=JSON.parse('{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors.","frontmatter":{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors."},"headers":[],"relativePath":"reference/prompt.md","filePath":"reference/prompt.md"}'),n={name:"reference/prompt.md"};function p(r,s,l,o,h,d){return t(),i("div",null,[...s[0]||(s[0]=[a("",11)])])}const m=e(n,[["render",p]]);export{c as __pageData,m as default};
1
+ import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors.","frontmatter":{"title":"prompt","description":"Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors."},"headers":[],"relativePath":"reference/prompt.md","filePath":"reference/prompt.md"}'),n={name:"reference/prompt.md"};function p(r,s,l,o,h,d){return t(),i("div",null,[...s[0]||(s[0]=[a("",11)])])}const m=e(n,[["render",p]]);export{c as __pageData,m as default};
@@ -1,4 +1,4 @@
1
- import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.dypDpWZ3.js";const E=JSON.parse('{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime.","frontmatter":{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime."},"headers":[],"relativePath":"reference/schedules.md","filePath":"reference/schedules.md"}'),t={name:"reference/schedules.md"};function h(l,s,p,k,d,r){return n(),a("div",null,[...s[0]||(s[0]=[e(`<h1 id="schedules-and-reminders" tabindex="-1">Schedules and reminders <a class="header-anchor" href="#schedules-and-reminders" aria-label="Permalink to &quot;Schedules and reminders&quot;">​</a></h1><p>Two ways an agent acts without an inbound message. A schedule is deploy-time cron: &quot;every weekday at 09:00, summarize open incidents.&quot; A reminder is a runtime wake bound to one conversation: &quot;re-check this PR&#39;s CI in two hours.&quot; Schedules live in the filesystem; reminders are created by running code.</p><h2 id="schedules" tabindex="-1">Schedules <a class="header-anchor" href="#schedules" aria-label="Permalink to &quot;Schedules&quot;">​</a></h2><p>Cron expressions are standard 5-field, evaluated in UTC with minute granularity.</p><h3 id="schedules-in-markdown" tabindex="-1">Schedules in Markdown <a class="header-anchor" href="#schedules-in-markdown" aria-label="Permalink to &quot;Schedules in Markdown&quot;">​</a></h3><p>A plain markdown file with <code>cron:</code> frontmatter is a fire-and-forget task:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
1
+ import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.BNw1pucY.js";const E=JSON.parse('{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime.","frontmatter":{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime."},"headers":[],"relativePath":"reference/schedules.md","filePath":"reference/schedules.md"}'),t={name:"reference/schedules.md"};function h(l,s,p,k,d,r){return n(),a("div",null,[...s[0]||(s[0]=[e(`<h1 id="schedules-and-reminders" tabindex="-1">Schedules and reminders <a class="header-anchor" href="#schedules-and-reminders" aria-label="Permalink to &quot;Schedules and reminders&quot;">​</a></h1><p>Two ways an agent acts without an inbound message. A schedule is deploy-time cron: &quot;every weekday at 09:00, summarize open incidents.&quot; A reminder is a runtime wake bound to one conversation: &quot;re-check this PR&#39;s CI in two hours.&quot; Schedules live in the filesystem; reminders are created by running code.</p><h2 id="schedules" tabindex="-1">Schedules <a class="header-anchor" href="#schedules" aria-label="Permalink to &quot;Schedules&quot;">​</a></h2><p>Cron expressions are standard 5-field, evaluated in UTC with minute granularity.</p><h3 id="schedules-in-markdown" tabindex="-1">Schedules in Markdown <a class="header-anchor" href="#schedules-in-markdown" aria-label="Permalink to &quot;Schedules in Markdown&quot;">​</a></h3><p>A plain markdown file with <code>cron:</code> frontmatter is a fire-and-forget task:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
2
2
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">cron: &quot;0 9 * * 1-5&quot;</span></span>
3
3
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
4
4
  <span class="line"></span>
@@ -1 +1 @@
1
- import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.dypDpWZ3.js";const E=JSON.parse('{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime.","frontmatter":{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime."},"headers":[],"relativePath":"reference/schedules.md","filePath":"reference/schedules.md"}'),t={name:"reference/schedules.md"};function h(l,s,p,k,d,r){return n(),a("div",null,[...s[0]||(s[0]=[e("",38)])])}const c=i(t,[["render",h]]);export{E as __pageData,c as default};
1
+ import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.BNw1pucY.js";const E=JSON.parse('{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime.","frontmatter":{"title":"Schedules & reminders","description":"Cron-driven runs defined at deploy time, and per-session durable wakes created at runtime."},"headers":[],"relativePath":"reference/schedules.md","filePath":"reference/schedules.md"}'),t={name:"reference/schedules.md"};function h(l,s,p,k,d,r){return n(),a("div",null,[...s[0]||(s[0]=[e("",38)])])}const c=i(t,[["render",h]]);export{E as __pageData,c as default};
@@ -1 +1 @@
1
- import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.dypDpWZ3.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 d(i,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 lock only for writes: a write-effect call returns <code>409 session_busy</code> while a model turn is running, a read-effect call runs alongside the turn (see <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>).</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>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>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. When <code>agent/result.ts</code> is authored, a thrown <code>commit</code>, a <code>ctx.reject</code> that exhausts the two-repair budget, or empty assistant text emits <code>turn.failed</code> instead of <code>turn.completed</code>. <code>ctx.reject(message)</code> re-runs the same turn with that message so the model can revise while tools and the session filesystem are still up.</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 in the session workspace, 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 lives under <code>--state-root</code>. Slugged mounts store it under a subdirectory named for the slug.</p><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. Cloud conversations remain on the Cursor backend.</p><p>Nested git checkouts already default <code>local.cwd</code> outside the enclosing repo. See <a href="#what-goes-into-a-local-session-workspace">What goes into a local session workspace?</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 saved trace:</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:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">state-roo</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;">/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></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></ul>',44)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
1
+ import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.BNw1pucY.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 d(i,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 lock only for writes: a write-effect call returns <code>409 session_busy</code> while a model turn is running, a read-effect call runs alongside the turn (see <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>).</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>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>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. When <code>agent/result.ts</code> is authored, a thrown <code>commit</code>, a <code>ctx.reject</code> that exhausts the two-repair budget, or empty assistant text emits <code>turn.failed</code> instead of <code>turn.completed</code>. <code>ctx.reject(message)</code> re-runs the same turn with that message so the model can revise while tools and the session filesystem are still up.</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 in the session workspace, 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 lives under <code>--state-root</code>. Slugged mounts store it under a subdirectory named for the slug.</p><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. Cloud conversations remain on the Cursor backend.</p><p>Nested git checkouts already default <code>local.cwd</code> outside the enclosing repo. See <a href="#what-goes-into-a-local-session-workspace">What goes into a local session workspace?</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 saved trace:</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:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">state-roo</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;">/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></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></ul>',44)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
@@ -1 +1 @@
1
- import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.dypDpWZ3.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 d(i,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o("",44)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
1
+ import{_ as t,c as s,o as a,a3 as o}from"./chunks/framework.BNw1pucY.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 d(i,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o("",44)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
@@ -1,4 +1,4 @@
1
- import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.dypDpWZ3.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),n={name:"reference/skills.md"};function l(o,s,h,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a(`<h1 id="skills" tabindex="-1">Skills <a class="header-anchor" href="#skills" aria-label="Permalink to &quot;Skills&quot;">​</a></h1><p>A skill is an on-demand procedure following the <code>SKILL.md</code> convention: the harness advertises each skill by its description, and the model loads the full content only when the task calls for it. Skills are how you give an agent a multi-step workflow without carrying it in the always-on <a href="./instructions.html">instructions</a>.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to &quot;Authoring forms&quot;">​</a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/skills/&lt;name&gt;.md</code></td><td>Flat markdown. Optional <code>description</code> frontmatter; the first body line is the fallback.</td></tr><tr><td><code>agent/skills/&lt;name&gt;/SKILL.md</code> plus siblings</td><td>A packaged directory with reference files (<code>references/…</code>). Requires <code>description</code> frontmatter.</td></tr><tr><td><code>agent/skills/&lt;name&gt;.ts</code></td><td>Generated content, with <code>defineSkill</code> from <code>@cursor/july/skills</code>.</td></tr></tbody></table><p>Flat markdown:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
1
+ import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),n={name:"reference/skills.md"};function l(o,s,h,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a(`<h1 id="skills" tabindex="-1">Skills <a class="header-anchor" href="#skills" aria-label="Permalink to &quot;Skills&quot;">​</a></h1><p>A skill is an on-demand procedure following the <code>SKILL.md</code> convention: the harness advertises each skill by its description, and the model loads the full content only when the task calls for it. Skills are how you give an agent a multi-step workflow without carrying it in the always-on <a href="./instructions.html">instructions</a>.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to &quot;Authoring forms&quot;">​</a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/skills/&lt;name&gt;.md</code></td><td>Flat markdown. Optional <code>description</code> frontmatter; the first body line is the fallback.</td></tr><tr><td><code>agent/skills/&lt;name&gt;/SKILL.md</code> plus siblings</td><td>A packaged directory with reference files (<code>references/…</code>). Requires <code>description</code> frontmatter.</td></tr><tr><td><code>agent/skills/&lt;name&gt;.ts</code></td><td>Generated content, with <code>defineSkill</code> from <code>@cursor/july/skills</code>.</td></tr></tbody></table><p>Flat markdown:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
2
2
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">description: Use when a pull request needs a structured approval checklist.</span></span>
3
3
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
4
4
  <span class="line"></span>
@@ -1 +1 @@
1
- import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.dypDpWZ3.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),n={name:"reference/skills.md"};function l(o,s,h,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a("",19)])])}const u=e(n,[["render",l]]);export{c as __pageData,u as default};
1
+ import{_ as e,c as i,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),n={name:"reference/skills.md"};function l(o,s,h,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a("",19)])])}const u=e(n,[["render",l]]);export{c as __pageData,u as default};
@@ -1,4 +1,4 @@
1
- import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.dypDpWZ3.js";const u=JSON.parse('{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/.","frontmatter":{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/."},"headers":[],"relativePath":"reference/subagents.md","filePath":"reference/subagents.md"}'),i={name:"reference/subagents.md"};function o(r,e,l,d,h,p){return a(),t("div",null,[...e[0]||(e[0]=[n(`<h1 id="subagents" tabindex="-1">Subagents <a class="header-anchor" href="#subagents" aria-label="Permalink to &quot;Subagents&quot;">​</a></h1><p>A subagent is a specialist child agent the model can delegate to mid-turn. Each one is its own directory under <code>agent/subagents/&lt;id&gt;/</code>, with the same <code>agent.ts</code> + <code>instructions.md</code> shape as the root. On the Cursor harness, subagents run as SDK custom subagents: the parent model delegates through the harness <code>task</code> tool, and the stream records <code>subagent.called</code> and <code>subagent.completed</code>.</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>agent/subagents/researcher/</span></span>
1
+ import{_ as s,c as a,o as t,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/.","frontmatter":{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/."},"headers":[],"relativePath":"reference/subagents.md","filePath":"reference/subagents.md"}'),i={name:"reference/subagents.md"};function o(r,e,l,d,h,p){return t(),a("div",null,[...e[0]||(e[0]=[n(`<h1 id="subagents" tabindex="-1">Subagents <a class="header-anchor" href="#subagents" aria-label="Permalink to &quot;Subagents&quot;">​</a></h1><p>A subagent is a specialist child agent the model can delegate to mid-turn. Each one is its own directory under <code>agent/subagents/&lt;id&gt;/</code>, with the same <code>agent.ts</code> + <code>instructions.md</code> shape as the root. On the Cursor harness, subagents run as SDK custom subagents: the parent model delegates through the harness <code>task</code> tool, and the stream records <code>subagent.called</code> and <code>subagent.completed</code>.</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>agent/subagents/researcher/</span></span>
2
2
  <span class="line"><span>├── agent.ts # description (required), model (optional)</span></span>
3
3
  <span class="line"><span>└── instructions.md # the subagent&#39;s own system prompt</span></span></code></pre></div><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:#6A737D;--shiki-dark:#6A737D;">// agent/subagents/researcher/agent.ts</span></span>
4
4
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineAgent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
@@ -7,4 +7,4 @@ import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.dypDpWZ3.js";const u
7
7
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> description:</span></span>
8
8
  <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;Background research: climate history, records, comparisons across many cities.&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
9
9
  <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // model: omit to inherit the parent&#39;s model</span></span>
10
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="subagent-rules" tabindex="-1">Subagent rules <a class="header-anchor" href="#subagent-rules" aria-label="Permalink to &quot;Subagent rules&quot;">​</a></h2><p><code>description</code> is required. It&#39;s the only thing the parent model reads when deciding whether to delegate, so write it as a routing rule (&quot;Background research: …&quot;), the same discipline as a <a href="./skills.html">skill</a> description. <code>model</code> is optional; omit it to inherit the parent&#39;s model, or set it to run the specialist on a different one.</p><p>Subagents inherit the parent&#39;s execution surface. Every per-subagent capability directory is reported as a warning and ignored: <code>tools/</code>, <code>skills/</code>, <code>mcp-connections/</code> (and the legacy <code>connections/</code> alias), <code>host-connections/</code>, <code>channels/</code>, <code>schedules/</code>, <code>hooks/</code>, <code>sandbox/</code>, and nested <code>subagents/</code>.</p><p>Delegation needs both halves: the description makes it possible, and the parent&#39;s <a href="./instructions.html">instructions</a> make it happen. &quot;When a request needs background research, delegate to the <code>researcher</code> subagent.&quot;</p><h2 id="subagent-or-peer" tabindex="-1">Subagent or peer? <a class="header-anchor" href="#subagent-or-peer" aria-label="Permalink to &quot;Subagent or peer?&quot;">​</a></h2><p>Subagents split one job into roles inside a single agent. When the specialist is independently useful, with its own tools, sessions, and playground, make it a full agent. See <a href="./../guides/agent-to-agent.html#peer-or-subagent">Agent-to-agent</a>.</p><h2 id="patterns" tabindex="-1">Patterns <a class="header-anchor" href="#patterns" aria-label="Permalink to &quot;Patterns&quot;">​</a></h2><p>Fan-out reviews: a PR-approval agent can delegate to two review subagents that read a host-prepared <code>pr/</code> evidence tree and report prioritized findings, which the parent embeds in its approval comment.</p><p>Keep the parent lean: a subagent with focused instructions usually works better than a longer parent prompt with conditional sections. The parent routes; the specialist executes.</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="./skills.html">Skills</a>: when a procedure is enough and a child agent is overkill</li></ul>`,16)])])}const g=s(i,[["render",o]]);export{u as __pageData,g as default};
10
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="subagent-rules" tabindex="-1">Subagent rules <a class="header-anchor" href="#subagent-rules" aria-label="Permalink to &quot;Subagent rules&quot;">​</a></h2><p><code>description</code> is required. It&#39;s the only thing the parent model reads when deciding whether to delegate, so write it as a routing rule (&quot;Background research: …&quot;), the same discipline as a <a href="./skills.html">skill</a> description. <code>model</code> is optional; omit it to inherit the parent&#39;s model, or set it to run the specialist on a different one.</p><p>Subagents inherit the parent&#39;s execution surface. Every per-subagent capability directory is reported as a warning and ignored: <code>tools/</code>, <code>skills/</code>, <code>mcp-connections/</code> (and the legacy <code>connections/</code> alias), <code>host-connections/</code>, <code>channels/</code>, <code>schedules/</code>, <code>hooks/</code>, <code>sandbox/</code>, and nested <code>subagents/</code>.</p><p>Delegation needs both halves: the description makes it possible, and the parent&#39;s <a href="./instructions.html">instructions</a> make it happen. &quot;When a request needs background research, delegate to the <code>researcher</code> subagent.&quot;</p><h2 id="subagent-or-peer" tabindex="-1">Subagent or peer? <a class="header-anchor" href="#subagent-or-peer" aria-label="Permalink to &quot;Subagent or peer?&quot;">​</a></h2><p>Subagents split one job into roles inside a single agent. When the specialist is independently useful, with its own tools, sessions, and playground, make it a full agent. See <a href="./../guides/agent-to-agent.html#peer-or-subagent">Peer agents</a>.</p><h2 id="patterns" tabindex="-1">Patterns <a class="header-anchor" href="#patterns" aria-label="Permalink to &quot;Patterns&quot;">​</a></h2><p>Fan-out reviews: a PR-approval agent can delegate to two review subagents that read a host-prepared <code>pr/</code> evidence tree and report prioritized findings, which the parent embeds in its approval comment.</p><p>Keep the parent lean: a subagent with focused instructions usually works better than a longer parent prompt with conditional sections. The parent routes; the specialist executes.</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="./skills.html">Skills</a>: when a procedure is enough and a child agent is overkill</li></ul>`,16)])])}const g=s(i,[["render",o]]);export{u as __pageData,g as default};
@@ -1 +1 @@
1
- import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.dypDpWZ3.js";const u=JSON.parse('{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/.","frontmatter":{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/."},"headers":[],"relativePath":"reference/subagents.md","filePath":"reference/subagents.md"}'),i={name:"reference/subagents.md"};function o(r,e,l,d,h,p){return a(),t("div",null,[...e[0]||(e[0]=[n("",16)])])}const g=s(i,[["render",o]]);export{u as __pageData,g as default};
1
+ import{_ as s,c as a,o as t,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/.","frontmatter":{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/."},"headers":[],"relativePath":"reference/subagents.md","filePath":"reference/subagents.md"}'),i={name:"reference/subagents.md"};function o(r,e,l,d,h,p){return t(),a("div",null,[...e[0]||(e[0]=[n("",16)])])}const g=s(i,[["render",o]]);export{u as __pageData,g as default};