@cursor/july 0.1.89 → 0.1.91

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 (346) hide show
  1. package/AGENTS.md +8 -0
  2. package/README.md +98 -96
  3. package/dist/ab.d.ts +1 -1
  4. package/dist/ab.js +1 -1
  5. package/dist/artifacts.d.ts +1 -1
  6. package/dist/artifacts.js +1 -1
  7. package/dist/bin/agent-serve.js +20 -7
  8. package/dist/channels/slack/channel-watch.d.ts +1 -1
  9. package/dist/channels/slack/channel-watch.js +1 -1
  10. package/dist/channels/slack/slack-channel.js +1 -1
  11. package/dist/channels/slack/types.d.ts +2 -4
  12. package/dist/channels/slack/types.d.ts.map +1 -1
  13. package/dist/channels.d.ts +1 -1
  14. package/dist/channels.js +1 -1
  15. package/dist/connections.d.ts +1 -1
  16. package/dist/connections.js +1 -1
  17. package/dist/docs/404.html +3 -3
  18. package/dist/docs/ab.html +7 -7
  19. package/dist/docs/assets/{ab.md.DYjwREAP.js → ab.md.CVzWxLoB.js} +1 -1
  20. package/dist/docs/assets/{ab.md.DYjwREAP.lean.js → ab.md.CVzWxLoB.lean.js} +1 -1
  21. package/dist/docs/assets/{app.DUOPbN18.js → app.Bci6CM9E.js} +1 -1
  22. package/dist/docs/assets/{building-with-agents.md.PeZaZA1P.js → building-with-agents.md.DH8A_cHA.js} +1 -1
  23. package/dist/docs/assets/{building-with-agents.md.PeZaZA1P.lean.js → building-with-agents.md.DH8A_cHA.lean.js} +1 -1
  24. package/dist/docs/assets/chunks/@localSearchIndexroot.Dv-Q0XtU.js +1 -0
  25. package/dist/docs/assets/chunks/{VPLocalSearchBox.CmWbGcGk.js → VPLocalSearchBox.BCPT6xA-.js} +1 -1
  26. package/dist/docs/assets/chunks/{framework.CAZyNGu9.js → framework.BCISBCiQ.js} +1 -1
  27. package/dist/docs/assets/chunks/theme.BEA8BF3c.js +2 -0
  28. package/dist/docs/assets/{concepts.md.BXAm6G-C.js → concepts.md.CRfU3bVg.js} +1 -1
  29. package/dist/docs/assets/{concepts.md.BXAm6G-C.lean.js → concepts.md.CRfU3bVg.lean.js} +1 -1
  30. package/dist/docs/assets/{deployment.md.B8kW-h7P.js → deployment.md.DX_hc3ze.js} +6 -5
  31. package/dist/docs/assets/{deployment.md.B8kW-h7P.lean.js → deployment.md.DX_hc3ze.lean.js} +1 -1
  32. package/dist/docs/assets/{evals.md.CVe_O75-.js → evals.md.a0SMN6r9.js} +3 -3
  33. package/dist/docs/assets/{evals.md.CVe_O75-.lean.js → evals.md.a0SMN6r9.lean.js} +1 -1
  34. package/dist/docs/assets/{example-agents_approval-buddy.md.CIiZ9coo.js → example-agents_approval-buddy.md.DNL83puR.js} +1 -1
  35. package/dist/docs/assets/{example-agents_approval-buddy.md.CIiZ9coo.lean.js → example-agents_approval-buddy.md.DNL83puR.lean.js} +1 -1
  36. package/dist/docs/assets/{example-agents_benny.md.B-LIDGja.js → example-agents_benny.md.C40vHRLc.js} +1 -1
  37. package/dist/docs/assets/{example-agents_benny.md.B-LIDGja.lean.js → example-agents_benny.md.C40vHRLc.lean.js} +1 -1
  38. package/dist/docs/assets/{example-agents_bugbot.md.Dp5JqHSQ.js → example-agents_bugbot.md.BRGMi9O2.js} +1 -1
  39. package/dist/docs/assets/{example-agents_bugbot.md.Dp5JqHSQ.lean.js → example-agents_bugbot.md.BRGMi9O2.lean.js} +1 -1
  40. package/dist/docs/assets/{example-agents_codebase-wiki.md.D-lteFf0.js → example-agents_codebase-wiki.md.Dftj_tPp.js} +1 -1
  41. package/dist/docs/assets/{example-agents_codebase-wiki.md.D-lteFf0.lean.js → example-agents_codebase-wiki.md.Dftj_tPp.lean.js} +1 -1
  42. package/dist/docs/assets/{example-agents_codeowners-review.md.BU2ZXLf-.js → example-agents_codeowners-review.md.Bfta-lBU.js} +1 -1
  43. package/dist/docs/assets/{example-agents_codeowners-review.md.BU2ZXLf-.lean.js → example-agents_codeowners-review.md.Bfta-lBU.lean.js} +1 -1
  44. package/dist/docs/assets/{example-agents_concierge.md.DA2al_NK.js → example-agents_concierge.md.MrKpQndp.js} +1 -1
  45. package/dist/docs/assets/{example-agents_concierge.md.DA2al_NK.lean.js → example-agents_concierge.md.MrKpQndp.lean.js} +1 -1
  46. package/dist/docs/assets/{example-agents_fsd.md.ZeGEpAw_.js → example-agents_fsd.md.ZWHWWZPE.js} +1 -1
  47. package/dist/docs/assets/{example-agents_fsd.md.ZeGEpAw_.lean.js → example-agents_fsd.md.ZWHWWZPE.lean.js} +1 -1
  48. package/dist/docs/assets/example-agents_index.md.QZ8mhr6n.js +2 -0
  49. package/dist/docs/assets/{example-agents_index.md.xmJ87d_3.lean.js → example-agents_index.md.QZ8mhr6n.lean.js} +1 -1
  50. package/dist/docs/assets/{example-agents_knowledge-base.md.IneynQSR.js → example-agents_knowledge-base.md.DqKqHQ9u.js} +1 -1
  51. package/dist/docs/assets/{example-agents_knowledge-base.md.IneynQSR.lean.js → example-agents_knowledge-base.md.DqKqHQ9u.lean.js} +1 -1
  52. package/dist/docs/assets/{example-agents_oncall.md.CBmyuAKc.js → example-agents_oncall.md.DK4XkYTd.js} +1 -1
  53. package/dist/docs/assets/{example-agents_oncall.md.CBmyuAKc.lean.js → example-agents_oncall.md.DK4XkYTd.lean.js} +1 -1
  54. package/dist/docs/assets/{example-agents_security-reviewer.md.DBL1TwtP.js → example-agents_security-reviewer.md.Bai6D0Ee.js} +4 -4
  55. package/dist/docs/assets/{example-agents_security-reviewer.md.DBL1TwtP.lean.js → example-agents_security-reviewer.md.Bai6D0Ee.lean.js} +1 -1
  56. package/dist/docs/assets/{example-agents_slack-agent.md.06jQXTAI.js → example-agents_slack-agent.md.D7Kdj5BV.js} +1 -1
  57. package/dist/docs/assets/{example-agents_slack-agent.md.06jQXTAI.lean.js → example-agents_slack-agent.md.D7Kdj5BV.lean.js} +1 -1
  58. package/dist/docs/assets/{example-agents_weather-agent.md.DC3lINjo.js → example-agents_weather-agent.md.lVEAbWFf.js} +5 -5
  59. package/dist/docs/assets/example-agents_weather-agent.md.lVEAbWFf.lean.js +1 -0
  60. package/dist/docs/assets/{guides_agent-to-agent.md.Bmbxy-FA.js → guides_agent-to-agent.md.BCeVdJRJ.js} +1 -1
  61. package/dist/docs/assets/{guides_agent-to-agent.md.Bmbxy-FA.lean.js → guides_agent-to-agent.md.BCeVdJRJ.lean.js} +1 -1
  62. package/dist/docs/assets/{guides_cloud-runtime.md.CbklWfzh.js → guides_cloud-runtime.md.BSMLIBHr.js} +1 -1
  63. package/dist/docs/assets/{guides_cloud-runtime.md.CbklWfzh.lean.js → guides_cloud-runtime.md.BSMLIBHr.lean.js} +1 -1
  64. package/dist/docs/assets/{guides_convert-automation.md.BhMzTkE5.js → guides_convert-automation.md.D06eIzea.js} +1 -1
  65. package/dist/docs/assets/{guides_convert-automation.md.BhMzTkE5.lean.js → guides_convert-automation.md.D06eIzea.lean.js} +1 -1
  66. package/dist/docs/assets/{guides_github.md.CLLQJKRB.js → guides_github.md.Cdt1s2QC.js} +4 -4
  67. package/dist/docs/assets/{guides_github.md.CLLQJKRB.lean.js → guides_github.md.Cdt1s2QC.lean.js} +1 -1
  68. package/dist/docs/assets/{guides_human-in-the-loop.md.Cf8kIIqC.js → guides_human-in-the-loop.md.By1G2T3_.js} +1 -1
  69. package/dist/docs/assets/{guides_human-in-the-loop.md.Cf8kIIqC.lean.js → guides_human-in-the-loop.md.By1G2T3_.lean.js} +1 -1
  70. package/dist/docs/assets/{guides_mcp-oauth.md.CzEB6RaG.js → guides_mcp-oauth.md.Du0f7pGU.js} +1 -1
  71. package/dist/docs/assets/{guides_mcp-oauth.md.CzEB6RaG.lean.js → guides_mcp-oauth.md.Du0f7pGU.lean.js} +1 -1
  72. package/dist/docs/assets/{guides_opentelemetry.md.Csn7ZI25.js → guides_opentelemetry.md.bmPmkvJu.js} +1 -1
  73. package/dist/docs/assets/{guides_opentelemetry.md.Csn7ZI25.lean.js → guides_opentelemetry.md.bmPmkvJu.lean.js} +1 -1
  74. package/dist/docs/assets/{guides_slack.md.DP4H75WP.js → guides_slack.md.DiUmk_Oi.js} +5 -5
  75. package/dist/docs/assets/{guides_slack.md.DP4H75WP.lean.js → guides_slack.md.DiUmk_Oi.lean.js} +1 -1
  76. package/dist/docs/assets/{guides_webhooks.md.DB-r_er9.js → guides_webhooks.md.BpnIdO0i.js} +5 -6
  77. package/dist/docs/assets/{guides_webhooks.md.DB-r_er9.lean.js → guides_webhooks.md.BpnIdO0i.lean.js} +1 -1
  78. package/dist/docs/assets/{hillclimbing.md.yXqdlv2R.js → hillclimbing.md.ywF3yDAd.js} +1 -1
  79. package/dist/docs/assets/{hillclimbing.md.yXqdlv2R.lean.js → hillclimbing.md.ywF3yDAd.lean.js} +1 -1
  80. package/dist/docs/assets/index.md.BAaMXLFd.js +5 -0
  81. package/dist/docs/assets/{index.md.DhRHS_-L.lean.js → index.md.BAaMXLFd.lean.js} +1 -1
  82. package/dist/docs/assets/{quickstart.md.DZxBu44y.js → quickstart.md.DsrarzEg.js} +1 -1
  83. package/dist/docs/assets/{quickstart.md.DZxBu44y.lean.js → quickstart.md.DsrarzEg.lean.js} +1 -1
  84. package/dist/docs/assets/{reference_agent-config.md.CTWp4DnU.js → reference_agent-config.md.Bqylgw50.js} +1 -1
  85. package/dist/docs/assets/{reference_agent-config.md.CTWp4DnU.lean.js → reference_agent-config.md.Bqylgw50.lean.js} +1 -1
  86. package/dist/docs/assets/{reference_artifacts.md.BGG4bZo-.js → reference_artifacts.md.Dior32Qw.js} +1 -1
  87. package/dist/docs/assets/{reference_artifacts.md.BGG4bZo-.lean.js → reference_artifacts.md.Dior32Qw.lean.js} +1 -1
  88. package/dist/docs/assets/{reference_channels.md.CboFd5IH.js → reference_channels.md.DQZjCnyh.js} +2 -2
  89. package/dist/docs/assets/{reference_channels.md.CboFd5IH.lean.js → reference_channels.md.DQZjCnyh.lean.js} +1 -1
  90. package/dist/docs/assets/{reference_cli.md.TAaYU8br.js → reference_cli.md.B7GkAJRC.js} +8 -7
  91. package/dist/docs/assets/{reference_cli.md.TAaYU8br.lean.js → reference_cli.md.B7GkAJRC.lean.js} +1 -1
  92. package/dist/docs/assets/{reference_connections.md.Cu3N-S3Q.js → reference_connections.md.DYidrb-j.js} +5 -5
  93. package/dist/docs/assets/{reference_connections.md.Cu3N-S3Q.lean.js → reference_connections.md.DYidrb-j.lean.js} +1 -1
  94. package/dist/docs/assets/{reference_hooks.md.DJE5DXcT.js → reference_hooks.md.B9FSgdDe.js} +1 -1
  95. package/dist/docs/assets/{reference_hooks.md.DJE5DXcT.lean.js → reference_hooks.md.B9FSgdDe.lean.js} +1 -1
  96. package/dist/docs/assets/{reference_http-api.md.DMbdFGVQ.js → reference_http-api.md.CSHVobzG.js} +4 -4
  97. package/dist/docs/assets/{reference_http-api.md.DMbdFGVQ.lean.js → reference_http-api.md.CSHVobzG.lean.js} +1 -1
  98. package/dist/docs/assets/{reference_instructions.md.CgoV-YEb.js → reference_instructions.md.DhNCOl7r.js} +1 -1
  99. package/dist/docs/assets/{reference_instructions.md.CgoV-YEb.lean.js → reference_instructions.md.DhNCOl7r.lean.js} +1 -1
  100. package/dist/docs/assets/{reference_playground.md.CPZhfYaO.js → reference_playground.md.Dfb92yQf.js} +1 -1
  101. package/dist/docs/assets/{reference_playground.md.CPZhfYaO.lean.js → reference_playground.md.Dfb92yQf.lean.js} +1 -1
  102. package/dist/docs/assets/{reference_project-layout.md.D3MdHM2z.js → reference_project-layout.md.CwkSbEWT.js} +5 -20
  103. package/dist/docs/assets/reference_project-layout.md.CwkSbEWT.lean.js +1 -0
  104. package/dist/docs/assets/{reference_prompt.md.BaiweQxE.js → reference_prompt.md.DZUMtLPD.js} +1 -1
  105. package/dist/docs/assets/{reference_prompt.md.BaiweQxE.lean.js → reference_prompt.md.DZUMtLPD.lean.js} +1 -1
  106. package/dist/docs/assets/{reference_schedules.md.gmfYzf_I.js → reference_schedules.md.DNipebiG.js} +1 -1
  107. package/dist/docs/assets/{reference_schedules.md.gmfYzf_I.lean.js → reference_schedules.md.DNipebiG.lean.js} +1 -1
  108. package/dist/docs/assets/{reference_sessions.md.B0DdlM-K.js → reference_sessions.md.tUFzz98S.js} +1 -1
  109. package/dist/docs/assets/{reference_sessions.md.B0DdlM-K.lean.js → reference_sessions.md.tUFzz98S.lean.js} +1 -1
  110. package/dist/docs/assets/{reference_skills.md.BRF2nDv9.js → reference_skills.md.B5ZEuHfG.js} +1 -1
  111. package/dist/docs/assets/{reference_skills.md.BRF2nDv9.lean.js → reference_skills.md.B5ZEuHfG.lean.js} +1 -1
  112. package/dist/docs/assets/{reference_subagents.md.DSrGLIuB.js → reference_subagents.md.Xoav0AII.js} +1 -1
  113. package/dist/docs/assets/{reference_subagents.md.DSrGLIuB.lean.js → reference_subagents.md.Xoav0AII.lean.js} +1 -1
  114. package/dist/docs/assets/{reference_tools.md.DTg_kEsx.js → reference_tools.md.wpaJtHn6.js} +23 -3
  115. package/dist/docs/assets/{reference_tools.md.DTg_kEsx.lean.js → reference_tools.md.wpaJtHn6.lean.js} +1 -1
  116. package/dist/docs/assets/{scaffolding-agents.md.CiGsJ1aw.js → scaffolding-agents.md.CRDDUtYJ.js} +1 -1
  117. package/dist/docs/assets/{scaffolding-agents.md.CiGsJ1aw.lean.js → scaffolding-agents.md.CRDDUtYJ.lean.js} +1 -1
  118. package/dist/docs/assets/{storage.md.ks1u64_R.js → storage.md.JbjlHWZ6.js} +1 -1
  119. package/dist/docs/assets/{storage.md.ks1u64_R.lean.js → storage.md.JbjlHWZ6.lean.js} +1 -1
  120. package/dist/docs/assets/{style.kTsvp4pE.css → style.BRuM8477.css} +1 -1
  121. package/dist/docs/assets/{templates_agentic-owners.md.BkTLORaU.js → templates_agentic-owners.md.DSJSIpWU.js} +1 -1
  122. package/dist/docs/assets/{templates_agentic-owners.md.BkTLORaU.lean.js → templates_agentic-owners.md.DSJSIpWU.lean.js} +1 -1
  123. package/dist/docs/assets/{templates_demo.md.Bgd6MBaZ.js → templates_demo.md.DhFcWN6j.js} +1 -1
  124. package/dist/docs/assets/{templates_demo.md.Bgd6MBaZ.lean.js → templates_demo.md.DhFcWN6j.lean.js} +1 -1
  125. package/dist/docs/assets/{templates_pr-autofixer.md.DcmoeUNZ.js → templates_pr-autofixer.md.1HAR3RXE.js} +1 -1
  126. package/dist/docs/assets/{templates_pr-autofixer.md.DcmoeUNZ.lean.js → templates_pr-autofixer.md.1HAR3RXE.lean.js} +1 -1
  127. package/dist/docs/assets/{templates_security-reviewer.md.C0yIUaYs.js → templates_security-reviewer.md.ByFyRta2.js} +1 -1
  128. package/dist/docs/assets/{templates_security-reviewer.md.C0yIUaYs.lean.js → templates_security-reviewer.md.ByFyRta2.lean.js} +1 -1
  129. package/dist/docs/assets/{templates_triage.md.DWuQ1bZz.js → templates_triage.md.CVlpctKS.js} +2 -2
  130. package/dist/docs/assets/{templates_triage.md.DWuQ1bZz.lean.js → templates_triage.md.CVlpctKS.lean.js} +1 -1
  131. package/dist/docs/assets/troubleshooting.md.DYECCZiJ.js +1 -0
  132. package/dist/docs/assets/{troubleshooting.md.KgmmaCgw.lean.js → troubleshooting.md.DYECCZiJ.lean.js} +1 -1
  133. package/dist/docs/building-with-agents.html +7 -7
  134. package/dist/docs/concepts.html +7 -7
  135. package/dist/docs/deployment.html +11 -10
  136. package/dist/docs/evals.html +8 -8
  137. package/dist/docs/example-agents/approval-buddy.html +7 -7
  138. package/dist/docs/example-agents/benny.html +7 -7
  139. package/dist/docs/example-agents/bugbot.html +7 -7
  140. package/dist/docs/example-agents/codebase-wiki.html +7 -7
  141. package/dist/docs/example-agents/codeowners-review.html +7 -7
  142. package/dist/docs/example-agents/concierge.html +7 -7
  143. package/dist/docs/example-agents/fsd.html +7 -7
  144. package/dist/docs/example-agents/index.html +7 -7
  145. package/dist/docs/example-agents/knowledge-base.html +7 -7
  146. package/dist/docs/example-agents/oncall.html +7 -7
  147. package/dist/docs/example-agents/security-reviewer.html +10 -10
  148. package/dist/docs/example-agents/slack-agent.html +7 -7
  149. package/dist/docs/example-agents/weather-agent.html +12 -12
  150. package/dist/docs/guides/agent-to-agent.html +7 -7
  151. package/dist/docs/guides/cloud-runtime.html +7 -7
  152. package/dist/docs/guides/convert-automation.html +7 -7
  153. package/dist/docs/guides/github.html +9 -9
  154. package/dist/docs/guides/human-in-the-loop.html +7 -7
  155. package/dist/docs/guides/mcp-oauth.html +7 -7
  156. package/dist/docs/guides/opentelemetry.html +7 -7
  157. package/dist/docs/guides/slack.html +10 -10
  158. package/dist/docs/guides/webhooks.html +10 -11
  159. package/dist/docs/hashmap.json +1 -1
  160. package/dist/docs/hillclimbing.html +7 -7
  161. package/dist/docs/index.html +8 -8
  162. package/dist/docs/quickstart.html +7 -7
  163. package/dist/docs/reference/agent-config.html +7 -7
  164. package/dist/docs/reference/artifacts.html +7 -7
  165. package/dist/docs/reference/channels.html +8 -8
  166. package/dist/docs/reference/cli.html +13 -12
  167. package/dist/docs/reference/connections.html +10 -10
  168. package/dist/docs/reference/hooks.html +7 -7
  169. package/dist/docs/reference/http-api.html +10 -10
  170. package/dist/docs/reference/instructions.html +7 -7
  171. package/dist/docs/reference/playground.html +7 -7
  172. package/dist/docs/reference/project-layout.html +10 -25
  173. package/dist/docs/reference/prompt.html +7 -7
  174. package/dist/docs/reference/schedules.html +7 -7
  175. package/dist/docs/reference/sessions.html +7 -7
  176. package/dist/docs/reference/skills.html +7 -7
  177. package/dist/docs/reference/subagents.html +7 -7
  178. package/dist/docs/reference/tools.html +29 -9
  179. package/dist/docs/scaffolding-agents.html +7 -7
  180. package/dist/docs/storage.html +7 -7
  181. package/dist/docs/templates/agentic-owners.html +7 -7
  182. package/dist/docs/templates/demo.html +7 -7
  183. package/dist/docs/templates/pr-autofixer.html +7 -7
  184. package/dist/docs/templates/security-reviewer.html +7 -7
  185. package/dist/docs/templates/triage.html +8 -8
  186. package/dist/docs/troubleshooting.html +7 -7
  187. package/dist/evals.d.ts +1 -1
  188. package/dist/evals.js +1 -1
  189. package/dist/hooks.d.ts +1 -1
  190. package/dist/hooks.js +1 -1
  191. package/dist/index.d.ts +2 -2
  192. package/dist/index.js +2 -2
  193. package/dist/internal/cli-convert-automation.d.ts +1 -1
  194. package/dist/internal/cli-convert-automation.js +1 -1
  195. package/dist/internal/cli-cursor.d.ts +12 -4
  196. package/dist/internal/cli-cursor.d.ts.map +1 -1
  197. package/dist/internal/cli-cursor.js +11 -4
  198. package/dist/internal/cli-deploy.d.ts.map +1 -1
  199. package/dist/internal/cli-deploy.js +21 -3
  200. package/dist/internal/convert-automation/convert-workflow.d.ts +1 -1
  201. package/dist/internal/convert-automation/convert-workflow.js +9 -9
  202. package/dist/internal/convert-automation/types.d.ts +1 -1
  203. package/dist/internal/convert-automation/types.js +1 -1
  204. package/dist/internal/cursor/backend-client.d.ts +9 -1
  205. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  206. package/dist/internal/cursor/backend-client.js +19 -6
  207. package/dist/internal/cursor/credentials.d.ts +35 -9
  208. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  209. package/dist/internal/cursor/credentials.js +92 -39
  210. package/dist/internal/cursor-agent-template.d.ts +1 -1
  211. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  212. package/dist/internal/cursor-agent-template.js +1 -0
  213. package/dist/internal/deploy-client.d.ts +18 -0
  214. package/dist/internal/deploy-client.d.ts.map +1 -1
  215. package/dist/internal/deploy-client.js +25 -1
  216. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  217. package/dist/internal/deploy-manifest.js +5 -1
  218. package/dist/internal/discovery.d.ts +5 -1
  219. package/dist/internal/discovery.d.ts.map +1 -1
  220. package/dist/internal/discovery.js +17 -1
  221. package/dist/internal/distribution.d.ts +18 -0
  222. package/dist/internal/distribution.d.ts.map +1 -1
  223. package/dist/internal/distribution.js +19 -0
  224. package/dist/internal/eval-runner.js +1 -1
  225. package/dist/internal/grokbot/runner.d.ts +5 -2
  226. package/dist/internal/grokbot/runner.d.ts.map +1 -1
  227. package/dist/internal/grokbot/runner.js +10 -6
  228. package/dist/internal/http-channel.d.ts +2 -2
  229. package/dist/internal/http-channel.d.ts.map +1 -1
  230. package/dist/internal/http-channel.js +11 -31
  231. package/dist/internal/init-project.d.ts.map +1 -1
  232. package/dist/internal/init-project.js +10 -1
  233. package/dist/internal/sdk-runner.d.ts +5 -0
  234. package/dist/internal/sdk-runner.d.ts.map +1 -1
  235. package/dist/internal/sdk-runner.js +10 -5
  236. package/dist/internal/server.d.ts.map +1 -1
  237. package/dist/internal/server.js +80 -36
  238. package/dist/internal/session-engine.d.ts +8 -0
  239. package/dist/internal/session-engine.d.ts.map +1 -1
  240. package/dist/internal/session-engine.js +47 -5
  241. package/dist/playground/assets/index-D9N7-q97.css +1 -0
  242. package/dist/playground/assets/{index-BmiIjFlM.js → index-DDvyC2z6.js} +49 -49
  243. package/dist/playground/index.html +2 -2
  244. package/dist/reminders.d.ts +1 -1
  245. package/dist/reminders.js +1 -1
  246. package/dist/schedules.d.ts +1 -1
  247. package/dist/schedules.js +1 -1
  248. package/dist/skills.d.ts +1 -1
  249. package/dist/skills.js +1 -1
  250. package/dist/storage.d.ts +1 -1
  251. package/dist/storage.js +1 -1
  252. package/dist/tools.d.ts +1 -1
  253. package/dist/tools.js +1 -1
  254. package/dist/types.d.ts +10 -7
  255. package/dist/types.d.ts.map +1 -1
  256. package/dist/types.js +1 -1
  257. package/docs/README.md +3 -1
  258. package/docs/concepts.md +2 -1
  259. package/docs/deployment.md +9 -6
  260. package/docs/evals.md +1 -5
  261. package/docs/example-agents/codebase-wiki.md +2 -3
  262. package/docs/example-agents/fsd.md +1 -1
  263. package/docs/example-agents/index.md +2 -2
  264. package/docs/example-agents/knowledge-base.md +3 -3
  265. package/docs/example-agents/security-reviewer.md +17 -48
  266. package/docs/example-agents/weather-agent.md +14 -45
  267. package/docs/guides/github.md +7 -4
  268. package/docs/guides/slack.md +7 -2
  269. package/docs/guides/webhooks.md +12 -15
  270. package/docs/reference/channels.md +4 -0
  271. package/docs/reference/cli.md +21 -7
  272. package/docs/reference/connections.md +13 -32
  273. package/docs/reference/http-api.md +14 -9
  274. package/docs/reference/project-layout.md +5 -20
  275. package/docs/reference/tools.md +51 -3
  276. package/docs/scaffolding-agents.md +2 -0
  277. package/docs/templates/triage.md +3 -5
  278. package/docs/troubleshooting.md +1 -1
  279. package/package.json +2 -1
  280. package/skills/create-agent/SKILL.md +6 -7
  281. package/skills/framework-map/SKILL.md +6 -6
  282. package/skills/setup-slack/SKILL.md +1 -1
  283. package/src/ab.ts +1 -1
  284. package/src/artifacts.ts +1 -1
  285. package/src/bin/agent-serve.ts +20 -6
  286. package/src/channels/slack/channel-watch.ts +1 -1
  287. package/src/channels/slack/slack-channel.ts +1 -1
  288. package/src/channels/slack/types.ts +2 -4
  289. package/src/channels.ts +1 -1
  290. package/src/connections.ts +1 -1
  291. package/src/evals.ts +1 -1
  292. package/src/hooks.ts +1 -1
  293. package/src/index.ts +2 -2
  294. package/src/internal/cli-convert-automation.ts +1 -1
  295. package/src/internal/cli-cursor.ts +18 -5
  296. package/src/internal/cli-deploy.ts +27 -7
  297. package/src/internal/convert-automation/convert-workflow.ts +9 -9
  298. package/src/internal/convert-automation/types.ts +1 -1
  299. package/src/internal/cursor/backend-client.ts +29 -4
  300. package/src/internal/cursor/credentials.ts +87 -24
  301. package/src/internal/cursor-agent-template.ts +1 -0
  302. package/src/internal/deploy-client.ts +40 -1
  303. package/src/internal/deploy-manifest.ts +10 -1
  304. package/src/internal/discovery.ts +21 -1
  305. package/src/internal/distribution.ts +31 -0
  306. package/src/internal/eval-runner.ts +1 -1
  307. package/src/internal/grokbot/runner.ts +15 -6
  308. package/src/internal/http-channel.ts +14 -41
  309. package/src/internal/init-project.ts +13 -1
  310. package/src/internal/sdk-runner.ts +10 -4
  311. package/src/internal/server.ts +95 -33
  312. package/src/internal/session-engine.ts +58 -8
  313. package/src/reminders.ts +1 -1
  314. package/src/schedules.ts +1 -1
  315. package/src/skills.ts +1 -1
  316. package/src/storage.ts +1 -1
  317. package/src/tools.ts +1 -1
  318. package/src/types.ts +10 -7
  319. package/templates/security-help/README.md +37 -0
  320. package/templates/security-help/agent/agent.ts +18 -0
  321. package/templates/security-help/agent/channels/github.ts +13 -0
  322. package/templates/security-help/agent/channels/slack.ts +89 -0
  323. package/templates/security-help/agent/instructions.md +20 -0
  324. package/templates/security-help/agent/knowledge/faq/approvals.md +5 -0
  325. package/templates/security-help/agent/knowledge/faq/channels.md +6 -0
  326. package/templates/security-help/agent/knowledge/faq/phishing.md +10 -0
  327. package/templates/security-help/agent/lib/pr-first-pass.ts +42 -0
  328. package/templates/security-help/agent/lib/repos.ts +5 -0
  329. package/templates/security-help/agent/skills/access-request.md +10 -0
  330. package/templates/security-help/agent/skills/security-first-pass.md +15 -0
  331. package/templates/security-help/agent/skills/security-playbooks.md +12 -0
  332. package/templates/security-help/agent/skills/security-pr-first-pass.md +12 -0
  333. package/templates/security-help/evals/evals.config.ts +5 -0
  334. package/templates/security-help/evals/security-help.eval.ts +53 -0
  335. package/templates/security-help/init.json +31 -0
  336. package/templates/security-help/package.json +18 -0
  337. package/templates/security-help/tsconfig.json +12 -0
  338. package/templates/triage/agent/channels/webhook.ts +2 -2
  339. package/dist/docs/assets/chunks/@localSearchIndexroot.CxCtxfDE.js +0 -1
  340. package/dist/docs/assets/chunks/theme.S57OeOLA.js +0 -2
  341. package/dist/docs/assets/example-agents_index.md.xmJ87d_3.js +0 -2
  342. package/dist/docs/assets/example-agents_weather-agent.md.DC3lINjo.lean.js +0 -1
  343. package/dist/docs/assets/index.md.DhRHS_-L.js +0 -5
  344. package/dist/docs/assets/reference_project-layout.md.D3MdHM2z.lean.js +0 -1
  345. package/dist/docs/assets/troubleshooting.md.KgmmaCgw.js +0 -1
  346. package/dist/playground/assets/index-DQGZnAI0.css +0 -1
@@ -296,6 +296,12 @@ async function parseRpcResponse(
296
296
  export interface CursorBackendClientOptions {
297
297
  backendUrl: string;
298
298
  apiKey: string;
299
+ /**
300
+ * Re-read the key on each authenticated call. Hosted freeze listens
301
+ * unsigned and the binder drops the key after restore; a constructor-frozen
302
+ * key would miss that bind.
303
+ */
304
+ getApiKey?: () => string;
299
305
  logger?: (line: string) => void;
300
306
  /** Test seam; defaults to global fetch. */
301
307
  fetchImpl?: typeof fetch;
@@ -303,21 +309,26 @@ export interface CursorBackendClientOptions {
303
309
 
304
310
  export class CursorBackendClient {
305
311
  private readonly backendUrl: string;
306
- private readonly apiKey: string;
312
+ private readonly resolveApiKey: () => string;
307
313
  private readonly logger: (line: string) => void;
308
314
  private readonly fetchImpl: typeof fetch;
309
315
  private token: { value: string; expiresAtMs: number } | undefined;
310
316
  private tokenExchange: Promise<string> | undefined;
317
+ private lastExchangedApiKey: string | undefined;
311
318
 
312
319
  constructor(options: CursorBackendClientOptions) {
313
320
  this.backendUrl = options.backendUrl.endsWith("/")
314
321
  ? options.backendUrl.slice(0, -1)
315
322
  : options.backendUrl;
316
- this.apiKey = options.apiKey;
323
+ this.resolveApiKey = options.getApiKey ?? (() => options.apiKey);
317
324
  this.logger = options.logger ?? (() => {});
318
325
  this.fetchImpl = options.fetchImpl ?? fetch;
319
326
  }
320
327
 
328
+ private currentApiKey(): string {
329
+ return this.resolveApiKey().trim();
330
+ }
331
+
321
332
  /** Who this API key acts as. */
322
333
  async getMe(): Promise<CursorIdentity> {
323
334
  return getMeResponseSchema.parse(await this.rpc("GetMe", {}));
@@ -443,7 +454,7 @@ export class CursorBackendClient {
443
454
  method: "POST",
444
455
  headers: {
445
456
  "content-type": "application/json",
446
- authorization: `Bearer ${this.apiKey}`,
457
+ authorization: `Bearer ${this.currentApiKey()}`,
447
458
  },
448
459
  body: JSON.stringify({ repos: [...repos], permissions }),
449
460
  signal: AbortSignal.timeout(30_000),
@@ -525,6 +536,18 @@ export class CursorBackendClient {
525
536
  * when none is cached or it is near expiry.
526
537
  */
527
538
  private getAccessToken(): Promise<string> {
539
+ const apiKey = this.currentApiKey();
540
+ if (apiKey === "") {
541
+ return Promise.reject(
542
+ new CursorBackendError(
543
+ "The Cursor backend client has no API key yet. Bind CURSOR_API_KEY or CURSOR_API_KEY_FILE before authenticated calls."
544
+ )
545
+ );
546
+ }
547
+ if (this.lastExchangedApiKey !== apiKey) {
548
+ this.token = undefined;
549
+ this.tokenExchange = undefined;
550
+ }
528
551
  if (
529
552
  this.token !== undefined &&
530
553
  Date.now() < this.token.expiresAtMs - TOKEN_EXPIRY_LEEWAY_MS
@@ -541,13 +564,14 @@ export class CursorBackendClient {
541
564
  }
542
565
 
543
566
  private async exchangeApiKey(): Promise<string> {
567
+ const apiKey = this.currentApiKey();
544
568
  let response: Response;
545
569
  try {
546
570
  response = await this.fetchImpl(`${this.backendUrl}${EXCHANGE_PATH}`, {
547
571
  method: "POST",
548
572
  headers: {
549
573
  "content-type": "application/json",
550
- authorization: `Bearer ${this.apiKey}`,
574
+ authorization: `Bearer ${apiKey}`,
551
575
  },
552
576
  body: "{}",
553
577
  signal: AbortSignal.timeout(30_000),
@@ -576,6 +600,7 @@ export class CursorBackendClient {
576
600
  value: body.data.accessToken,
577
601
  expiresAtMs: jwtExpiryMs(body.data.accessToken),
578
602
  };
603
+ this.lastExchangedApiKey = apiKey;
579
604
  this.logger("[agent-sdk] cursor account: minted a fresh access token");
580
605
  return body.data.accessToken;
581
606
  }
@@ -9,6 +9,10 @@
9
9
  * dashboard-revocable user API key — only the key is stored.
10
10
  * - `CURSOR_API_KEY` (or `serve({ apiKey })`) wins over the stored key, so
11
11
  * CI and hosted deployments stay env-driven.
12
+ * - `CURSOR_API_KEY_FILE` (or the hosted default path) is next: freeze bind
13
+ * drops the key at task time without restarting July.
14
+ * - Stored `july login` is last. Same order for hosted and self-hosted:
15
+ * option → env → file → login.
12
16
  *
13
17
  * There is deliberately no session-token storage, refresh-token rotation, or
14
18
  * cross-tool credential sharing here: short-lived access tokens are minted
@@ -16,6 +20,7 @@
16
20
  */
17
21
 
18
22
  import { createHash, randomBytes, randomUUID } from "node:crypto";
23
+ import { readFileSync } from "node:fs";
19
24
  import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
20
25
  import { homedir } from "node:os";
21
26
  import { dirname, join } from "node:path";
@@ -43,10 +48,11 @@ export function cursorBackendUrl(): string {
43
48
 
44
49
  /**
45
50
  * External API base URL for routes served only by the external-api
46
- * microlith (`/internal/agent-serve/*`, engine aliases). In production
47
- * these are mounted on api.cursor.com and 404 on api2.cursor.sh, so the
48
- * deploy surface needs its own default. `CURSOR_API_BASE_URL` still
49
- * overrides everything for local dev, where one server mounts all routes.
51
+ * microlith (`/internal/agent-serve/*`, `/v0/grokbot/*`, engine aliases).
52
+ * In production these are mounted on api.cursor.com and 404 on
53
+ * api2.cursor.sh, so the deploy surface needs its own default.
54
+ * `CURSOR_API_BASE_URL` still overrides everything for local dev, where
55
+ * one server mounts all routes.
50
56
  */
51
57
  export function cursorExternalApiUrl(): string {
52
58
  return trimTrailingSlash(
@@ -100,20 +106,13 @@ export function credentialsFilePath(): string {
100
106
  return join(configDirPath(), "credentials.json");
101
107
  }
102
108
 
103
- export async function readStoredCredentials(): Promise<
104
- StoredCredentials | undefined
105
- > {
106
- let raw: string;
107
- try {
108
- raw = await readFile(credentialsFilePath(), "utf8");
109
- } catch {
110
- return undefined;
111
- }
109
+ function parseStoredCredentialsJson(
110
+ raw: string
111
+ ): StoredCredentials | undefined {
112
112
  let parsed: unknown;
113
113
  try {
114
114
  parsed = JSON.parse(raw) as unknown;
115
115
  } catch {
116
- // Corrupt file — treat as signed out; login rewrites it.
117
116
  return undefined;
118
117
  }
119
118
  const credentials = storedCredentialsSchema.safeParse(parsed);
@@ -126,6 +125,28 @@ export async function readStoredCredentials(): Promise<
126
125
  };
127
126
  }
128
127
 
128
+ export function readStoredCredentialsSync(): StoredCredentials | undefined {
129
+ let raw: string;
130
+ try {
131
+ raw = readFileSync(credentialsFilePath(), "utf8");
132
+ } catch {
133
+ return undefined;
134
+ }
135
+ return parseStoredCredentialsJson(raw);
136
+ }
137
+
138
+ export async function readStoredCredentials(): Promise<
139
+ StoredCredentials | undefined
140
+ > {
141
+ let raw: string;
142
+ try {
143
+ raw = await readFile(credentialsFilePath(), "utf8");
144
+ } catch {
145
+ return undefined;
146
+ }
147
+ return parseStoredCredentialsJson(raw);
148
+ }
149
+
129
150
  export async function writeStoredCredentials(
130
151
  credentials: StoredCredentials
131
152
  ): Promise<void> {
@@ -148,10 +169,10 @@ export async function clearStoredCredentials(): Promise<boolean> {
148
169
  }
149
170
 
150
171
  // ============================================================================
151
- // Resolution (option > env > stored login)
172
+ // Resolution (option > env > file > stored login)
152
173
  // ============================================================================
153
174
 
154
- export type ApiKeySource = "option" | "env" | "login";
175
+ export type ApiKeySource = "option" | "env" | "file" | "login";
155
176
 
156
177
  export interface ResolvedApiKey {
157
178
  apiKey: string;
@@ -160,15 +181,43 @@ export interface ResolvedApiKey {
160
181
  }
161
182
 
162
183
  /**
163
- * Resolve the account API key for `backendUrl` (defaults to the active
164
- * backend): explicit option `CURSOR_API_KEY` stored login. A stored key
165
- * minted against a different backend is ignored rather than sent to the
166
- * wrong host.
184
+ * Hosted task-bind path. Not a secret: the snapshot may name this path.
185
+ * The binder writes the key here after restore; July re-reads on each use.
186
+ * Override with `CURSOR_API_KEY_FILE`. A missing file is unsigned self-hosted
187
+ * then uses `CURSOR_API_KEY` or stored login.
167
188
  */
168
- export async function resolveApiKey(options?: {
189
+ export const DEFAULT_CURSOR_API_KEY_FILE: string =
190
+ "/run/cursor/secrets/CURSOR_API_KEY";
191
+
192
+ /**
193
+ * Read `CURSOR_API_KEY_FILE` (or {@link DEFAULT_CURSOR_API_KEY_FILE} when
194
+ * unset). Missing/empty files are unsigned, not an error — freeze bake
195
+ * listens before the binder drops the key; self-hosted falls through to
196
+ * env or login.
197
+ */
198
+ export function readApiKeyFromFile(filePath?: string): string | undefined {
199
+ const configured = filePath ?? process.env.CURSOR_API_KEY_FILE;
200
+ const path =
201
+ configured !== undefined && configured.trim() !== ""
202
+ ? configured.trim()
203
+ : DEFAULT_CURSOR_API_KEY_FILE;
204
+ try {
205
+ const raw = readFileSync(path, "utf8").trim();
206
+ return raw === "" ? undefined : raw;
207
+ } catch {
208
+ return undefined;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * First present source wins. We define the order; operators do not.
214
+ * `--api-key` / `serve({ apiKey })` → `CURSOR_API_KEY` → `CURSOR_API_KEY_FILE`
215
+ * (hosted default path if unset) → stored `july login`.
216
+ */
217
+ export function resolveApiKeySync(options?: {
169
218
  apiKey?: string;
170
219
  backendUrl?: string;
171
- }): Promise<ResolvedApiKey | undefined> {
220
+ }): ResolvedApiKey | undefined {
172
221
  const backendUrl = options?.backendUrl ?? cursorBackendUrl();
173
222
  if (options?.apiKey !== undefined && options.apiKey.trim() !== "") {
174
223
  return { apiKey: options.apiKey.trim(), source: "option", backendUrl };
@@ -177,15 +226,29 @@ export async function resolveApiKey(options?: {
177
226
  if (envKey !== undefined && envKey.trim() !== "") {
178
227
  return { apiKey: envKey.trim(), source: "env", backendUrl };
179
228
  }
180
- const stored = await readStoredCredentials();
229
+ const fileKey = readApiKeyFromFile();
230
+ if (fileKey !== undefined) {
231
+ return { apiKey: fileKey, source: "file", backendUrl };
232
+ }
233
+ const stored = readStoredCredentialsSync();
181
234
  if (stored !== undefined && stored.backendUrl === backendUrl) {
182
235
  return { apiKey: stored.apiKey, source: "login", backendUrl };
183
236
  }
184
237
  return undefined;
185
238
  }
186
239
 
240
+ /**
241
+ * {@link resolveApiKeySync} as a Promise for call sites that already await.
242
+ */
243
+ export async function resolveApiKey(options?: {
244
+ apiKey?: string;
245
+ backendUrl?: string;
246
+ }): Promise<ResolvedApiKey | undefined> {
247
+ return resolveApiKeySync(options);
248
+ }
249
+
187
250
  /** One-line hint for "no credentials" errors, shared across surfaces. */
188
- export const SIGN_IN_HINT: string = `Run \`${CLI_COMMAND_NAME} login\` (or set CURSOR_API_KEY / pass serve({ apiKey })).`;
251
+ export const SIGN_IN_HINT: string = `Run \`${CLI_COMMAND_NAME} login\` (or set CURSOR_API_KEY / CURSOR_API_KEY_FILE / pass serve({ apiKey })).`;
189
252
 
190
253
  // ============================================================================
191
254
  // PKCE browser login (mirrors cursor-agent / Sand)
@@ -6,6 +6,7 @@ const TEMPLATE_NAMES = [
6
6
  "agentic-owners",
7
7
  "demo",
8
8
  "pr-autofixer",
9
+ "security-help",
9
10
  "security-reviewer",
10
11
  "triage-linear",
11
12
  "triage-jira",
@@ -255,6 +255,17 @@ export interface AgentkitDeployStatus {
255
255
  export const TERMINAL_AGENTKIT_DEPLOY_STATUSES: ReadonlySet<AgentkitCustomerStatus> =
256
256
  new Set(["running", "failed", "stopped"]);
257
257
 
258
+ /**
259
+ * `POST /internal/agentkit/deployments/:slug/stop` 202 body. Like v1
260
+ * {@link StopAccepted} but keyed by catalog ids instead of the numeric
261
+ * deployment row id.
262
+ */
263
+ export interface AgentkitStopAccepted {
264
+ applicationId: string;
265
+ releaseId: string;
266
+ status: string;
267
+ }
268
+
258
269
  /** One secret's metadata from the list endpoint — names only, never values. */
259
270
  export interface SecretInfo {
260
271
  name: string;
@@ -332,6 +343,14 @@ const agentkitDeployStatusSchema = z
332
343
  })
333
344
  .passthrough();
334
345
 
346
+ const agentkitStopAcceptedSchema = z
347
+ .object({
348
+ applicationId: z.string().min(1),
349
+ releaseId: z.string().min(1),
350
+ status: z.string(),
351
+ })
352
+ .passthrough();
353
+
335
354
  const deploymentSchema = z.object({
336
355
  id: z.number(),
337
356
  slug: z.string(),
@@ -602,6 +621,22 @@ export class AgentServeDeployClient {
602
621
  return agentkitDeployStatusSchema.parse(raw);
603
622
  }
604
623
 
624
+ /**
625
+ * Stop a v2 deployment (`POST /internal/agentkit/deployments/:slug/stop`).
626
+ * 202 means accepted; poll {@link getAgentkitDeploy} until `stopped`.
627
+ */
628
+ async stopAgentkit(args: {
629
+ teamId: number;
630
+ slug: string;
631
+ }): Promise<AgentkitStopAccepted> {
632
+ const raw = await this.request({
633
+ method: "POST",
634
+ path: `/internal/agentkit/deployments/${encodeURIComponent(args.slug)}/stop?teamId=${args.teamId}`,
635
+ context: { verb: "stop", slug: args.slug },
636
+ });
637
+ return agentkitStopAcceptedSchema.parse(raw);
638
+ }
639
+
605
640
  async listDeployments(args: { teamId: number }): Promise<Deployment[]> {
606
641
  const raw = await this.request({
607
642
  method: "GET",
@@ -888,8 +923,12 @@ function mapErrorResponse(
888
923
  );
889
924
  }
890
925
  case 409:
926
+ // The server's 409 body distinguishes real conflicts (CAS races,
927
+ // "still deploying", architecture-v2 slugs on the v1 surface); keep
928
+ // its message when present.
891
929
  return new DeployApiError(
892
- `A concurrent deploy or stop is changing deployment${slugPart}; retry in a moment.`,
930
+ serverError ??
931
+ `A concurrent deploy or stop is changing deployment${slugPart}; retry in a moment.`,
893
932
  409
894
933
  );
895
934
  case 429: {
@@ -40,7 +40,10 @@ import {
40
40
  handshakeChannelContinuation,
41
41
  } from "./continuation-channel.js";
42
42
  import { CONTINUATION_SELECTORS } from "./continuation-identity.js";
43
- import { projectInfo } from "./discovery.js";
43
+ import {
44
+ projectInfo,
45
+ runtimeArchitectureCompatibilityError,
46
+ } from "./discovery.js";
44
47
  import { packageVersion } from "./distribution.js";
45
48
 
46
49
  export const DEPLOY_MANIFEST_VERSION: 1 = 1;
@@ -125,6 +128,12 @@ export function buildAgentDeployManifest(
125
128
  project: AgentProject,
126
129
  options?: { nowMs?: number; cliVersion?: string }
127
130
  ): AgentDeployManifestV1 {
131
+ const runtimeArchitectureError = runtimeArchitectureCompatibilityError(
132
+ project.agent
133
+ );
134
+ if (runtimeArchitectureError !== undefined) {
135
+ throw new Error(runtimeArchitectureError);
136
+ }
128
137
  applyAgentContinuationDefaults(project);
129
138
  const channels = project.channels.map((channel) => {
130
139
  const handshake = handshakeChannelContinuation(channel);
@@ -524,6 +524,17 @@ async function loadAgent(
524
524
  const hosting = resolveHosting(ctx, agentDir, config?.hosting);
525
525
  const concurrency = resolveConcurrency(ctx, agentDir, config?.concurrency);
526
526
  const architecture = resolveArchitecture(ctx, agentDir, config?.architecture);
527
+ const runtimeArchitectureError = runtimeArchitectureCompatibilityError({
528
+ runtime,
529
+ architecture,
530
+ });
531
+ if (runtimeArchitectureError !== undefined) {
532
+ ctx.diagnostics.push({
533
+ severity: "error",
534
+ path: displayPath(ctx, join(agentDir, "agent.ts")),
535
+ message: runtimeArchitectureError,
536
+ });
537
+ }
527
538
 
528
539
  if (runtime === "cloud") {
529
540
  warnCloudRuntimeLimitations(ctx, agentDir, {
@@ -570,6 +581,15 @@ async function loadAgent(
570
581
  };
571
582
  }
572
583
 
584
+ export function runtimeArchitectureCompatibilityError(agent: {
585
+ runtime: AgentRuntime;
586
+ architecture?: AgentArchitecture;
587
+ }): string | undefined {
588
+ return agent.architecture === "v2" && agent.runtime === "grokbot"
589
+ ? 'architecture: "v2" cannot use runtime: "grokbot": the grokbot runtime executes through the signed-in account\'s hosted /v0/grokbot box, not a deployment-scoped v2 runtime.'
590
+ : undefined;
591
+ }
592
+
573
593
  function resolveArchitecture(
574
594
  ctx: DiscoveryContext,
575
595
  agentDir: string,
@@ -2021,7 +2041,7 @@ async function loadABConfig(
2021
2041
  severity: "error",
2022
2042
  path: displayPath(ctx, path),
2023
2043
  message:
2024
- "ab.config.ts must default-export defineABConfig({ ... }) from @anysphere/agent-serve/ab.",
2044
+ "ab.config.ts must default-export defineABConfig({ ... }) from @cursor/july/ab.",
2025
2045
  });
2026
2046
  return undefined;
2027
2047
  }
@@ -81,6 +81,37 @@ export function packageVersion(): string {
81
81
  return typeof parsed.version === "string" ? parsed.version : "0.0.0";
82
82
  }
83
83
 
84
+ /** Facts `agent-sdk version` / `--version` print. */
85
+ export interface CliVersionInfo {
86
+ /** Published npm name (`@cursor/july`). */
87
+ name: string;
88
+ /** `package.json` version of this install. */
89
+ version: string;
90
+ /** Bin the process was invoked as (`agent-sdk` / `agent-serve`). */
91
+ cli: string;
92
+ }
93
+
94
+ export function cliVersionInfo(): CliVersionInfo {
95
+ return {
96
+ name: PACKAGE_NAME,
97
+ version: packageVersion(),
98
+ cli: CLI_COMMAND_NAME,
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Text or JSON for `version` / `--version` / `-V`.
104
+ * Text is the bare `package.json` version (npm-style). `--json` is the
105
+ * complete `{ name, version, cli }` payload.
106
+ */
107
+ export function formatCliVersion(options?: { json?: boolean }): string {
108
+ const info = cliVersionInfo();
109
+ if (options?.json === true) {
110
+ return `${JSON.stringify(info, null, 2)}\n`;
111
+ }
112
+ return `${info.version}\n`;
113
+ }
114
+
84
115
  /**
85
116
  * Authoring entry subpaths and their dist-relative output files — the
86
117
  * runtime mirror of the package `exports` map (the source of truth;
@@ -479,7 +479,7 @@ function resolveEvalMaxConcurrency(config: Partial<EvalConfigFile>): number {
479
479
  if (config.maxConcurrency === undefined) {
480
480
  throw new Error(
481
481
  `evals/evals.config.ts must define maxConcurrency (1–${EVAL_MAX_CONCURRENCY_LIMIT}; hard limit is due to model provider request limits). Example:\n` +
482
- ` import { defineEvalConfig } from "@anysphere/agent-serve/evals";\n` +
482
+ ` import { defineEvalConfig } from "@cursor/july/evals";\n` +
483
483
  ` export default defineEvalConfig({ maxConcurrency: 20 });`
484
484
  );
485
485
  }
@@ -13,15 +13,21 @@
13
13
 
14
14
  import { randomUUID } from "node:crypto";
15
15
  import type { RunnerTurnRequest, TurnOutcome } from "../../types.js";
16
- import { cursorBackendUrl } from "../cursor/credentials.js";
16
+ import {
17
+ cursorExternalApiUrl,
18
+ resolveApiKeySync,
19
+ } from "../cursor/credentials.js";
17
20
  import type { AgentRunner } from "./../sdk-runner.js";
18
21
 
19
22
  export interface GrokBotRunnerOptions {
20
- /** Cursor API key. Defaults to the `CURSOR_API_KEY` environment variable. */
23
+ /** Cursor API key. Resolved as option env → file → stored login. */
21
24
  apiKey?: string;
22
25
  /** Test seam. Defaults to global fetch. */
23
26
  fetchImpl?: typeof fetch;
24
- /** Test seam. Defaults to {@link cursorBackendUrl}. */
27
+ /**
28
+ * Test seam. Defaults to {@link cursorExternalApiUrl} (`api.cursor.com`).
29
+ * `/v0/grokbot` is an external-api microlith route — it 404s on api2.
30
+ */
25
31
  backendUrl?: string;
26
32
  /** Test seam. Poll interval while a turn runs. */
27
33
  pollIntervalMs?: number;
@@ -89,14 +95,17 @@ class GrokBotApiClient {
89
95
 
90
96
  constructor(options: GrokBotRunnerOptions) {
91
97
  this.fetchImpl = options.fetchImpl ?? fetch;
92
- this.baseUrl = (options.backendUrl ?? cursorBackendUrl()).replace(
98
+ this.baseUrl = (options.backendUrl ?? cursorExternalApiUrl()).replace(
93
99
  /\/$/,
94
100
  ""
95
101
  );
96
- const apiKey = options.apiKey ?? process.env.CURSOR_API_KEY;
102
+ const apiKey = resolveApiKeySync({
103
+ apiKey: options.apiKey,
104
+ backendUrl: options.backendUrl,
105
+ })?.apiKey;
97
106
  if (apiKey === undefined || apiKey === "") {
98
107
  throw new Error(
99
- 'runtime: "grokbot" needs a Cursor API key (CURSOR_API_KEY or agent-sdk login) to reach the hosted Grok Bot harness.'
108
+ 'runtime: "grokbot" needs a Cursor API key (CURSOR_API_KEY, CURSOR_API_KEY_FILE, or agent-sdk login) to reach the hosted Grok Bot harness.'
100
109
  );
101
110
  }
102
111
  this.apiKey = apiKey;
@@ -7,8 +7,8 @@
7
7
  * Continuation semantics: `POST /v1/session` returns a `continuationToken`;
8
8
  * each accepted follow-up rotates it and returns the replacement, and a
9
9
  * stale token is rejected with 409. Follow-ups address any chat session by
10
- * id (including custom channels such as `drive`) when the token matches
11
- * that session's channel + key; task sessions stay fire-and-forget.
10
+ * id (including custom channels such as `drive`) when the token matches its
11
+ * active HTTP follow-up key; task sessions stay fire-and-forget.
12
12
  */
13
13
 
14
14
  import type {
@@ -20,11 +20,7 @@ import type {
20
20
  SessionRecord,
21
21
  } from "../types.js";
22
22
  import { samePrincipal } from "./auth.js";
23
- import {
24
- formatContinuationToken,
25
- newContinuationKey,
26
- parseContinuationToken,
27
- } from "./ids.js";
23
+ import { formatContinuationToken, parseContinuationToken } from "./ids.js";
28
24
  import { isLoopbackAddress } from "./net.js";
29
25
  import type { ServerRoute } from "./router.js";
30
26
  import {
@@ -32,7 +28,6 @@ import {
32
28
  ApprovalNotFoundError,
33
29
  HTTP_CHANNEL_ID,
34
30
  SessionAuthError,
35
- SessionBusyError,
36
31
  type SessionEngine,
37
32
  } from "./session-engine.js";
38
33
  import {
@@ -143,10 +138,8 @@ export function buildHttpChannelRoutes(args: {
143
138
  `Unknown session ${sessionId}.`
144
139
  );
145
140
  }
146
- // Playground (and other HTTP clients) may follow up on any chat
147
- // session including custom channels like `drive` — using that
148
- // session's own continuation token. Task/schedule sessions stay
149
- // fire-and-forget.
141
+ // HTTP can follow any chat session. Its credential is separate from the
142
+ // owning channel's continuation key.
150
143
  if (record.mode === "task") {
151
144
  return errorResponse(
152
145
  409,
@@ -178,12 +171,7 @@ export function buildHttpChannelRoutes(args: {
178
171
  );
179
172
  }
180
173
  const presented = parseContinuationToken(body.continuationToken);
181
- if (
182
- presented === null ||
183
- presented.channelId !== record.channelId ||
184
- record.continuationKey === null ||
185
- presented.key !== record.continuationKey
186
- ) {
174
+ if (presented === null) {
187
175
  return errorResponse(
188
176
  409,
189
177
  "stale_continuation_token",
@@ -192,34 +180,19 @@ export function buildHttpChannelRoutes(args: {
192
180
  }
193
181
 
194
182
  const message = await transformMessage(body.message, ctx.auth);
195
- try {
196
- // Continue as the session owner after the HTTP ownership gate so
197
- // `--dev` relaxed reads can follow up on channel-owned sessions
198
- // (drive/slack/…) without failing SessionAuthError.
199
- await engine.send(record.channelId, message, {
200
- auth: record.auth,
201
- continuationToken: record.continuationKey,
202
- });
203
- } catch (error) {
204
- if (error instanceof SessionBusyError) {
205
- return errorResponse(
206
- 409,
207
- "session_busy",
208
- "A turn is already running; wait for session.waiting before sending a follow-up."
209
- );
210
- }
211
- throw error;
183
+ const rotated = await engine.followUpHttp(sessionId, presented, message);
184
+ if (rotated === undefined) {
185
+ return errorResponse(
186
+ 409,
187
+ "stale_continuation_token",
188
+ "The continuation token does not address this session's active continuation."
189
+ );
212
190
  }
213
-
214
- // Rotate only after the message is accepted so a rejected send leaves
215
- // the caller's token valid for retry.
216
- const rotated = newContinuationKey();
217
- await engine.setContinuationToken(sessionId, rotated);
218
191
  return jsonResponse(
219
192
  {
220
193
  ok: true,
221
194
  sessionId,
222
- continuationToken: formatContinuationToken(record.channelId, rotated),
195
+ continuationToken: formatContinuationToken(HTTP_CHANNEL_ID, rotated),
223
196
  },
224
197
  { headers: { [SESSION_ID_HEADER]: sessionId } }
225
198
  );
@@ -6,6 +6,7 @@ import { spawn } from "node:child_process";
6
6
  import { existsSync } from "node:fs";
7
7
  import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
8
8
  import { basename, dirname, join, relative, resolve } from "node:path";
9
+ import { runfiles } from "@bazel/runfiles";
9
10
  import type { ModelSetting } from "../types.js";
10
11
  import {
11
12
  canonicalTemplateName,
@@ -75,6 +76,7 @@ const TEMPLATES: Readonly<Record<TemplateName, TemplateEntry>> = {
75
76
  "agentic-owners": { dir: "agentic-owners" },
76
77
  demo: { dir: "demo" },
77
78
  "pr-autofixer": { dir: "pr-autofixer" },
79
+ "security-help": { dir: "security-help" },
78
80
  "security-reviewer": { dir: "security-reviewer" },
79
81
  "triage-linear": { dir: "triage", overlay: "linear" },
80
82
  "triage-jira": { dir: "triage", overlay: "jira" },
@@ -103,7 +105,7 @@ export function resolveTemplate(name: string): TemplateResolution {
103
105
  };
104
106
  }
105
107
  const entry = TEMPLATES[resolved];
106
- const dir = join(packageRootDir(), "templates", entry.dir);
108
+ const dir = resolvePackagePath("templates", entry.dir);
107
109
  return {
108
110
  ok: true,
109
111
  name: resolved,
@@ -115,6 +117,15 @@ export function resolveTemplate(name: string): TemplateResolution {
115
117
  };
116
118
  }
117
119
 
120
+ function resolvePackagePath(...segments: string[]): string {
121
+ if (runfiles.workspace !== undefined) {
122
+ return runfiles.resolveWorkspaceRelative(
123
+ ["packages", "agent-serve", ...segments].join("/")
124
+ );
125
+ }
126
+ return join(packageRootDir(), ...segments);
127
+ }
128
+
118
129
  export type InitTargetCheck = { ok: true } | { ok: false; message: string };
119
130
 
120
131
  /**
@@ -699,6 +710,7 @@ Scaffold a project, then open the playground:
699
710
  npx ${PACKAGE_NAME} init ./my-agent # installs deps + links agent-sdk onto PATH
700
711
  npx ${PACKAGE_NAME} init ./my-demo --template demo # record a PR walkthrough
701
712
  npx ${PACKAGE_NAME} init ./my-reviewer --template security-reviewer # review PRs for security bugs
713
+ npx ${PACKAGE_NAME} init ./security-help --template security-help # answer security questions in Slack
702
714
  npx ${PACKAGE_NAME} init ./my-triage --template triage-linear # comment on Linear issues
703
715
  npx ${PACKAGE_NAME} init ./my-triage --template triage-jira # comment on Jira issues
704
716
  npx ${PACKAGE_NAME} init ./my-owners --template agentic-owners # review PRs via owners policies