@cursor/july 0.1.107 → 0.1.109

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 (523) hide show
  1. package/AGENTS.md +2 -6
  2. package/README.md +13 -11
  3. package/dist/bin/agent-serve.js +30 -8
  4. package/dist/channels/bitbucket/api.d.ts +41 -0
  5. package/dist/channels/bitbucket/api.d.ts.map +1 -1
  6. package/dist/channels/bitbucket/api.js +260 -0
  7. package/dist/channels/bitbucket/binding.d.ts +4 -0
  8. package/dist/channels/bitbucket/binding.d.ts.map +1 -1
  9. package/dist/channels/bitbucket/binding.js +16 -0
  10. package/dist/channels/bitbucket/index.d.ts +1 -1
  11. package/dist/channels/bitbucket/index.d.ts.map +1 -1
  12. package/dist/channels/bitbucket/index.js +1 -1
  13. package/dist/channels/github/github-channel.js +8 -5
  14. package/dist/channels/github/types.d.ts +5 -1
  15. package/dist/channels/github/types.d.ts.map +1 -1
  16. package/dist/channels/gitlab/api.d.ts +27 -0
  17. package/dist/channels/gitlab/api.d.ts.map +1 -1
  18. package/dist/channels/gitlab/api.js +88 -0
  19. package/dist/channels/gitlab/binding.d.ts +5 -0
  20. package/dist/channels/gitlab/binding.d.ts.map +1 -1
  21. package/dist/channels/gitlab/binding.js +10 -0
  22. package/dist/channels/gitlab/index.d.ts +1 -1
  23. package/dist/channels/gitlab/index.d.ts.map +1 -1
  24. package/dist/channels/gitlab/index.js +1 -1
  25. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  26. package/dist/channels/origin/origin-channel.js +27 -13
  27. package/dist/channels/origin/types.d.ts +5 -1
  28. package/dist/channels/origin/types.d.ts.map +1 -1
  29. package/dist/channels/slack/dispatch.d.ts +10 -0
  30. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  31. package/dist/channels/slack/dispatch.js +20 -3
  32. package/dist/channels/slack/slack-channel.d.ts +12 -5
  33. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  34. package/dist/channels/slack/slack-channel.js +59 -8
  35. package/dist/channels.d.ts +45 -0
  36. package/dist/channels.d.ts.map +1 -1
  37. package/dist/channels.js +106 -7
  38. package/dist/connections.d.ts +2 -1
  39. package/dist/connections.d.ts.map +1 -1
  40. package/dist/connections.js +2 -1
  41. package/dist/docs/404.html +2 -2
  42. package/dist/docs/assets/{app.CtuckIiL.js → app.Cr-wVbnB.js} +1 -1
  43. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.D0KbSkJn.js} +2 -2
  44. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.D0KbSkJn.lean.js} +1 -1
  45. package/dist/docs/assets/chunks/@localSearchIndexroot.CFVQ4S17.js +1 -0
  46. package/dist/docs/assets/chunks/{VPLocalSearchBox.Bkkhnu8K.js → VPLocalSearchBox.CVQERt56.js} +1 -1
  47. package/dist/docs/assets/chunks/{theme.DhpIe0Pa.js → theme.Dnsd3XOn.js} +2 -2
  48. package/dist/docs/assets/concepts.md.B4o63Gul.js +1 -0
  49. package/dist/docs/assets/{deployment.md.MFPKqsqI.js → deployment.md.JenwuCCB.js} +4 -4
  50. package/dist/docs/assets/{deployment.md.MFPKqsqI.lean.js → deployment.md.JenwuCCB.lean.js} +1 -1
  51. package/dist/docs/assets/evals.md.C7JLjoEP.js +211 -0
  52. package/dist/docs/assets/evals.md.C7JLjoEP.lean.js +1 -0
  53. package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.js +10 -0
  54. package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.lean.js +1 -0
  55. package/dist/docs/assets/guides_cloud-agents.md.BsloyHdY.js +9 -0
  56. package/dist/docs/assets/{guides_cloud-agents.md.DS8RIjwx.lean.js → guides_cloud-agents.md.BsloyHdY.lean.js} +1 -1
  57. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.js → guides_github.md.TZaTZlfz.js} +13 -3
  58. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.lean.js → guides_github.md.TZaTZlfz.lean.js} +1 -1
  59. package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.js +14 -0
  60. package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.lean.js +1 -0
  61. package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.js → guides_grokbot-agents.md.DyV-WArv.js} +1 -1
  62. package/dist/docs/assets/guides_improve.md.BGVk32bK.js +14 -0
  63. package/dist/docs/assets/guides_improve.md.BGVk32bK.lean.js +1 -0
  64. package/dist/docs/assets/{guides_slack.md.9oHPye9o.js → guides_slack.md.D4RVMM4G.js} +3 -3
  65. package/dist/docs/assets/{guides_slack.md.9oHPye9o.lean.js → guides_slack.md.D4RVMM4G.lean.js} +1 -1
  66. package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.CJK484ex.js} +2 -2
  67. package/dist/docs/assets/{hillclimbing.md.CpTGTCle.js → hillclimbing.md.BOiVo1tf.js} +1 -1
  68. package/dist/docs/assets/index.md.DD9Q2XuJ.js +5 -0
  69. package/dist/docs/assets/{index.md.BW_6tOgR.lean.js → index.md.DD9Q2XuJ.lean.js} +1 -1
  70. package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.js → reference_agent-config.md.CvoL6pof.js} +1 -1
  71. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js} +2 -2
  72. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.CAo-iK4j.lean.js} +1 -1
  73. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.js → reference_cli.md.Deg7849l.js} +7 -7
  74. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.lean.js → reference_cli.md.Deg7849l.lean.js} +1 -1
  75. package/dist/docs/assets/{reference_connections.md.Di6jJAXF.js → reference_connections.md.BojkC6c5.js} +1 -1
  76. package/dist/docs/assets/{reference_extensions.md.CGmMLblt.js → reference_extensions.md.ZAVUyuEX.js} +3 -3
  77. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.BlM_bOg6.js} +3 -3
  78. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.BlM_bOg6.lean.js} +1 -1
  79. package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.BwaCo-VO.js} +1 -1
  80. package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.DLnoaczX.js} +1 -1
  81. package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.DLnoaczX.lean.js} +1 -1
  82. package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.js → reference_project-layout.md.BEU8MtQV.js} +3 -3
  83. package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.BEU8MtQV.lean.js} +1 -1
  84. package/dist/docs/assets/reference_sessions.md.CyXV1MUw.js +1 -0
  85. package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.js → scaffolding-agents.md.Kctn3OVb.js} +1 -1
  86. package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.js → skills_create-agent.md.Q3h6Je-e.js} +1 -1
  87. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.js → skills_debug.md.CVjCXMFF.js} +1 -1
  88. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.lean.js → skills_debug.md.CVjCXMFF.lean.js} +1 -1
  89. package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.js +35 -0
  90. package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.lean.js +1 -0
  91. package/dist/docs/assets/skills_evals.md.DFxYPErF.js +25 -0
  92. package/dist/docs/assets/skills_evals.md.DFxYPErF.lean.js +1 -0
  93. package/dist/docs/assets/skills_framework-map.md.BxLSOhSY.js +1 -0
  94. package/dist/docs/assets/{skills_framework-map.md.haibFyoB.lean.js → skills_framework-map.md.BxLSOhSY.lean.js} +1 -1
  95. package/dist/docs/assets/{skills_github.md.D0JahM8c.js → skills_github.md.hgFX_oKY.js} +1 -1
  96. package/dist/docs/assets/skills_index.md.DL7EHaQ-.js +1 -0
  97. package/dist/docs/assets/skills_index.md.DL7EHaQ-.lean.js +1 -0
  98. package/dist/docs/assets/{storage.md.BOHeqk2M.js → storage.md.BUrhJ-Zz.js} +4 -4
  99. package/dist/docs/assets/{storage.md.BOHeqk2M.lean.js → storage.md.BUrhJ-Zz.lean.js} +1 -1
  100. package/dist/docs/assets/troubleshooting.md.CYEAO9bM.js +1 -0
  101. package/dist/docs/building-with-agents.html +5 -5
  102. package/dist/docs/building-with-agents.md +3 -2
  103. package/dist/docs/concepts.html +5 -5
  104. package/dist/docs/concepts.md +2 -4
  105. package/dist/docs/deployment.html +7 -7
  106. package/dist/docs/deployment.md +7 -2
  107. package/dist/docs/evals.html +161 -35
  108. package/dist/docs/evals.md +612 -296
  109. package/dist/docs/guides/agent-to-agent.html +4 -4
  110. package/dist/docs/guides/bitbucket.html +36 -0
  111. package/dist/docs/guides/bitbucket.md +84 -0
  112. package/dist/docs/guides/cloud-agents.html +6 -6
  113. package/dist/docs/guides/cloud-agents.md +4 -3
  114. package/dist/docs/guides/convert-automation.html +4 -4
  115. package/dist/docs/guides/github.html +17 -7
  116. package/dist/docs/guides/github.md +33 -1
  117. package/dist/docs/guides/gitlab.html +40 -0
  118. package/dist/docs/guides/gitlab.md +92 -0
  119. package/dist/docs/guides/grokbot-agents.html +6 -6
  120. package/dist/docs/guides/grokbot-agents.md +2 -2
  121. package/dist/docs/guides/human-in-the-loop.html +4 -4
  122. package/dist/docs/guides/improve.html +40 -0
  123. package/dist/docs/guides/improve.md +91 -0
  124. package/dist/docs/guides/mcp-oauth.html +4 -4
  125. package/dist/docs/guides/opentelemetry.html +5 -5
  126. package/dist/docs/guides/slack.html +7 -7
  127. package/dist/docs/guides/slack.md +2 -1
  128. package/dist/docs/guides/webhooks.html +6 -6
  129. package/dist/docs/guides/webhooks.md +4 -2
  130. package/dist/docs/hashmap.json +1 -1
  131. package/dist/docs/hillclimbing.html +6 -6
  132. package/dist/docs/hillclimbing.md +2 -2
  133. package/dist/docs/index.html +6 -6
  134. package/dist/docs/index.md +14 -6
  135. package/dist/docs/llms-full.txt +1274 -814
  136. package/dist/docs/llms.txt +7 -5
  137. package/dist/docs/quickstart.html +4 -4
  138. package/dist/docs/reference/agent-config.html +6 -6
  139. package/dist/docs/reference/agent-config.md +5 -2
  140. package/dist/docs/reference/artifacts.html +4 -4
  141. package/dist/docs/reference/channels.html +6 -6
  142. package/dist/docs/reference/channels.md +16 -3
  143. package/dist/docs/reference/cli.html +11 -11
  144. package/dist/docs/reference/cli.md +24 -15
  145. package/dist/docs/reference/connections.html +6 -6
  146. package/dist/docs/reference/connections.md +2 -1
  147. package/dist/docs/reference/extensions.html +8 -8
  148. package/dist/docs/reference/extensions.md +2 -3
  149. package/dist/docs/reference/hooks.html +7 -7
  150. package/dist/docs/reference/hooks.md +9 -12
  151. package/dist/docs/reference/http-api.html +6 -6
  152. package/dist/docs/reference/http-api.md +2 -3
  153. package/dist/docs/reference/instructions.html +4 -4
  154. package/dist/docs/reference/playground.html +5 -5
  155. package/dist/docs/reference/playground.md +0 -4
  156. package/dist/docs/reference/project-layout.html +7 -7
  157. package/dist/docs/reference/project-layout.md +1 -8
  158. package/dist/docs/reference/prompt.html +4 -4
  159. package/dist/docs/reference/result.html +4 -4
  160. package/dist/docs/reference/schedules.html +4 -4
  161. package/dist/docs/reference/sessions.html +5 -5
  162. package/dist/docs/reference/sessions.md +1 -2
  163. package/dist/docs/reference/skills.html +4 -4
  164. package/dist/docs/reference/subagents.html +4 -4
  165. package/dist/docs/reference/tools.html +4 -4
  166. package/dist/docs/scaffolding-agents.html +5 -5
  167. package/dist/docs/scaffolding-agents.md +2 -1
  168. package/dist/docs/skills/create-agent.html +6 -6
  169. package/dist/docs/skills/create-agent.md +1 -1
  170. package/dist/docs/skills/debug.html +5 -5
  171. package/dist/docs/skills/debug.md +1 -1
  172. package/dist/docs/skills/deploy.html +61 -0
  173. package/dist/docs/skills/deploy.md +161 -0
  174. package/dist/docs/skills/evals.html +8 -8
  175. package/dist/docs/skills/evals.md +44 -6
  176. package/dist/docs/skills/framework-map.html +5 -5
  177. package/dist/docs/skills/framework-map.md +5 -4
  178. package/dist/docs/skills/github.html +6 -6
  179. package/dist/docs/skills/github.md +1 -1
  180. package/dist/docs/skills/hillclimb.html +4 -4
  181. package/dist/docs/skills/index.html +6 -6
  182. package/dist/docs/skills/index.md +1 -1
  183. package/dist/docs/skills/mcp-auth.html +4 -4
  184. package/dist/docs/skills/otel.html +4 -4
  185. package/dist/docs/skills/setup-slack.html +4 -4
  186. package/dist/docs/storage.html +8 -8
  187. package/dist/docs/storage.md +15 -24
  188. package/dist/docs/templates/agentic-owners.html +4 -4
  189. package/dist/docs/templates/agents-md.html +4 -4
  190. package/dist/docs/templates/code-wiki.html +4 -4
  191. package/dist/docs/templates/demo.html +4 -4
  192. package/dist/docs/templates/grokbot-agents.html +4 -4
  193. package/dist/docs/templates/pr-autofixer.html +4 -4
  194. package/dist/docs/templates/security-help.html +4 -4
  195. package/dist/docs/templates/security-reviewer.html +4 -4
  196. package/dist/docs/templates/triage.html +4 -4
  197. package/dist/docs/troubleshooting.html +5 -5
  198. package/dist/docs/troubleshooting.md +1 -1
  199. package/dist/extensions/improve/extension.d.ts +46 -0
  200. package/dist/extensions/improve/extension.d.ts.map +1 -0
  201. package/dist/extensions/improve/extension.js +41 -0
  202. package/dist/extensions/improve/skills/yourself.d.ts +4 -0
  203. package/dist/extensions/improve/skills/yourself.d.ts.map +1 -0
  204. package/dist/extensions/improve/skills/yourself.js +43 -0
  205. package/dist/extensions.d.ts +2 -3
  206. package/dist/extensions.d.ts.map +1 -1
  207. package/dist/extensions.js +2 -5
  208. package/dist/index.d.ts +2 -3
  209. package/dist/index.d.ts.map +1 -1
  210. package/dist/index.js +1 -2
  211. package/dist/internal/authored-alias-hooks.d.ts +5 -0
  212. package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
  213. package/dist/internal/authored-alias-hooks.js +17 -0
  214. package/dist/internal/authored-loaders.d.ts +4 -0
  215. package/dist/internal/authored-loaders.d.ts.map +1 -1
  216. package/dist/internal/authored-loaders.js +21 -2
  217. package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
  218. package/dist/internal/builtin-tools/artifacts.js +2 -3
  219. package/dist/internal/channel-route-dispatch.d.ts +13 -0
  220. package/dist/internal/channel-route-dispatch.d.ts.map +1 -0
  221. package/dist/internal/channel-route-dispatch.js +62 -0
  222. package/dist/internal/channel-state.d.ts +17 -0
  223. package/dist/internal/channel-state.d.ts.map +1 -0
  224. package/dist/internal/channel-state.js +78 -0
  225. package/dist/internal/cli-ax.d.ts +8 -2
  226. package/dist/internal/cli-ax.d.ts.map +1 -1
  227. package/dist/internal/cli-ax.js +100 -3
  228. package/dist/internal/cli-cursor.d.ts.map +1 -1
  229. package/dist/internal/cli-cursor.js +2 -0
  230. package/dist/internal/cli-deploy.d.ts.map +1 -1
  231. package/dist/internal/cli-deploy.js +38 -14
  232. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  233. package/dist/internal/cli-mcp-oauth.js +15 -0
  234. package/dist/internal/cli-mcp.d.ts.map +1 -1
  235. package/dist/internal/cli-mcp.js +12 -0
  236. package/dist/internal/cli-slack.d.ts.map +1 -1
  237. package/dist/internal/cli-slack.js +8 -2
  238. package/dist/internal/continuation-channel.d.ts.map +1 -1
  239. package/dist/internal/continuation-channel.js +2 -2
  240. package/dist/internal/continuation-identity.js +8 -3
  241. package/dist/internal/cursor/credentials.d.ts +8 -2
  242. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  243. package/dist/internal/cursor/credentials.js +27 -5
  244. package/dist/internal/deploy-client.d.ts +27 -0
  245. package/dist/internal/deploy-client.d.ts.map +1 -1
  246. package/dist/internal/deploy-client.js +32 -0
  247. package/dist/internal/deploy-manifest.d.ts +23 -0
  248. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  249. package/dist/internal/deploy-manifest.js +84 -1
  250. package/dist/internal/describe-error.d.ts +1 -0
  251. package/dist/internal/describe-error.d.ts.map +1 -1
  252. package/dist/internal/describe-error.js +25 -0
  253. package/dist/internal/discovery/agent.d.ts +1 -1
  254. package/dist/internal/discovery/agent.d.ts.map +1 -1
  255. package/dist/internal/discovery/agent.js +0 -5
  256. package/dist/internal/discovery/extension-overlay.d.ts +1 -2
  257. package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
  258. package/dist/internal/discovery/extension-overlay.js +0 -14
  259. package/dist/internal/discovery/extensions.d.ts +1 -2
  260. package/dist/internal/discovery/extensions.d.ts.map +1 -1
  261. package/dist/internal/discovery/extensions.js +4 -22
  262. package/dist/internal/discovery/info.d.ts.map +1 -1
  263. package/dist/internal/discovery/info.js +42 -24
  264. package/dist/internal/discovery/modules.js +0 -1
  265. package/dist/internal/discovery/project.d.ts.map +1 -1
  266. package/dist/internal/discovery/project.js +0 -16
  267. package/dist/internal/eval-runner.js +0 -1
  268. package/dist/internal/framework-file-storage.d.ts +4 -5
  269. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  270. package/dist/internal/framework-file-storage.js +4 -5
  271. package/dist/internal/framework-storage-selection.d.ts +2 -2
  272. package/dist/internal/framework-storage-selection.js +2 -2
  273. package/dist/internal/guest-network.d.ts +4 -10
  274. package/dist/internal/guest-network.d.ts.map +1 -1
  275. package/dist/internal/guest-network.js +42 -26
  276. package/dist/internal/hosted-admission-adapter.d.ts +2 -0
  277. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  278. package/dist/internal/hosted-catch-protocol.d.ts +51 -0
  279. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -0
  280. package/dist/internal/hosted-catch-protocol.js +103 -0
  281. package/dist/internal/hosted-catch.d.ts +40 -0
  282. package/dist/internal/hosted-catch.d.ts.map +1 -0
  283. package/dist/internal/hosted-catch.js +149 -0
  284. package/dist/internal/hosted-delivery-protocol.d.ts +41 -0
  285. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  286. package/dist/internal/hosted-delivery-protocol.js +249 -0
  287. package/dist/internal/hosted-delivery.d.ts +10 -1
  288. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  289. package/dist/internal/hosted-delivery.js +100 -22
  290. package/dist/internal/hosted-execution-diag.d.ts +4 -1
  291. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  292. package/dist/internal/hosted-execution-diag.js +13 -4
  293. package/dist/internal/hosted-execution-flush.d.ts +3 -0
  294. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  295. package/dist/internal/hosted-execution-flush.js +2 -4
  296. package/dist/internal/http-control-plane-session.d.ts +30 -0
  297. package/dist/internal/http-control-plane-session.d.ts.map +1 -0
  298. package/dist/internal/http-control-plane-session.js +83 -0
  299. package/dist/internal/init-scaffold.d.ts.map +1 -1
  300. package/dist/internal/init-scaffold.js +1 -2
  301. package/dist/internal/install-cursor-skills.d.ts +5 -2
  302. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  303. package/dist/internal/install-cursor-skills.js +25 -5
  304. package/dist/internal/legacy-command-guard.d.ts +22 -0
  305. package/dist/internal/legacy-command-guard.d.ts.map +1 -0
  306. package/dist/internal/legacy-command-guard.js +51 -0
  307. package/dist/internal/platform-timers.d.ts +7 -0
  308. package/dist/internal/platform-timers.d.ts.map +1 -1
  309. package/dist/internal/platform-timers.js +139 -0
  310. package/dist/internal/reminder-control-plane-protocol.d.ts +2 -0
  311. package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -1
  312. package/dist/internal/reminder-control-plane-protocol.js +9 -2
  313. package/dist/internal/reminder-runner.d.ts +8 -0
  314. package/dist/internal/reminder-runner.d.ts.map +1 -1
  315. package/dist/internal/reminder-runner.js +36 -9
  316. package/dist/internal/resolve-prod-target.d.ts +2 -0
  317. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  318. package/dist/internal/resolve-prod-target.js +13 -0
  319. package/dist/internal/run-client.d.ts +1 -1
  320. package/dist/internal/sdk-runner.d.ts.map +1 -1
  321. package/dist/internal/sdk-runner.js +5 -4
  322. package/dist/internal/server.d.ts.map +1 -1
  323. package/dist/internal/server.js +57 -70
  324. package/dist/internal/session-engine.d.ts +7 -41
  325. package/dist/internal/session-engine.d.ts.map +1 -1
  326. package/dist/internal/session-engine.js +110 -227
  327. package/dist/internal/storage-coordinator.d.ts +5 -19
  328. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  329. package/dist/internal/storage-coordinator.js +3 -62
  330. package/dist/internal/storage-roles.d.ts +4 -9
  331. package/dist/internal/storage-roles.d.ts.map +1 -1
  332. package/dist/internal/storage-roles.js +2 -2
  333. package/dist/playground/assets/index-Bhxzrcf6.css +1 -0
  334. package/dist/playground/assets/index-CqLX5uF3.js +67 -0
  335. package/dist/playground/index.html +2 -2
  336. package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
  337. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
  338. package/dist/storage-backends/cursor-hosted-v2.js +4 -5
  339. package/dist/storage-backends/cursor-hosted.d.ts +7 -2
  340. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  341. package/dist/storage-backends/cursor-hosted.js +29 -31
  342. package/dist/storage-backends/file-kv.d.ts +9 -12
  343. package/dist/storage-backends/file-kv.d.ts.map +1 -1
  344. package/dist/storage-backends/file-kv.js +11 -47
  345. package/dist/storage-protocol.d.ts +3 -11
  346. package/dist/storage-protocol.d.ts.map +1 -1
  347. package/dist/storage-protocol.js +3 -11
  348. package/dist/storage.d.ts +8 -36
  349. package/dist/storage.d.ts.map +1 -1
  350. package/dist/storage.js +8 -44
  351. package/dist/types.d.ts +53 -62
  352. package/dist/types.d.ts.map +1 -1
  353. package/docs/README.md +14 -6
  354. package/docs/building-with-agents.md +3 -2
  355. package/docs/concepts.md +2 -4
  356. package/docs/deployment.md +7 -2
  357. package/docs/evals.md +613 -297
  358. package/docs/guides/bitbucket.md +89 -0
  359. package/docs/guides/cloud-agents.md +4 -3
  360. package/docs/guides/github.md +33 -1
  361. package/docs/guides/gitlab.md +97 -0
  362. package/docs/guides/grokbot-agents.md +2 -2
  363. package/docs/guides/improve.md +96 -0
  364. package/docs/guides/slack.md +2 -1
  365. package/docs/guides/webhooks.md +4 -2
  366. package/docs/hillclimbing.md +2 -2
  367. package/docs/reference/agent-config.md +5 -2
  368. package/docs/reference/channels.md +16 -3
  369. package/docs/reference/cli.md +24 -15
  370. package/docs/reference/connections.md +2 -1
  371. package/docs/reference/extensions.md +2 -3
  372. package/docs/reference/hooks.md +9 -12
  373. package/docs/reference/http-api.md +2 -3
  374. package/docs/reference/playground.md +0 -4
  375. package/docs/reference/project-layout.md +1 -8
  376. package/docs/reference/sessions.md +1 -2
  377. package/docs/scaffolding-agents.md +2 -1
  378. package/docs/skills/index.md +2 -2
  379. package/docs/storage.md +15 -24
  380. package/docs/troubleshooting.md +1 -1
  381. package/package.json +8 -7
  382. package/skills/create-agent/SKILL.md +1 -1
  383. package/skills/debug/SKILL.md +1 -1
  384. package/skills/deploy/SKILL.md +169 -0
  385. package/skills/evals/SKILL.md +45 -8
  386. package/skills/framework-map/SKILL.md +5 -4
  387. package/skills/github/SKILL.md +1 -1
  388. package/src/bin/agent-serve.ts +27 -2
  389. package/src/channels/bitbucket/api.ts +341 -0
  390. package/src/channels/bitbucket/binding.ts +25 -0
  391. package/src/channels/bitbucket/index.ts +2 -0
  392. package/src/channels/github/github-channel.ts +8 -8
  393. package/src/channels/github/types.ts +5 -0
  394. package/src/channels/gitlab/api.ts +123 -0
  395. package/src/channels/gitlab/binding.ts +12 -0
  396. package/src/channels/gitlab/index.ts +1 -0
  397. package/src/channels/origin/origin-channel.ts +29 -13
  398. package/src/channels/origin/types.ts +5 -0
  399. package/src/channels/slack/dispatch.ts +30 -0
  400. package/src/channels/slack/slack-channel.ts +69 -7
  401. package/src/channels.ts +157 -10
  402. package/src/connections.ts +2 -1
  403. package/src/extensions/improve/extension.ts +70 -0
  404. package/src/extensions/improve/skills/yourself.ts +50 -0
  405. package/src/extensions.ts +2 -6
  406. package/src/index.ts +0 -3
  407. package/src/internal/authored-alias-hooks.ts +32 -0
  408. package/src/internal/authored-loaders.ts +26 -2
  409. package/src/internal/builtin-tools/artifacts.ts +2 -3
  410. package/src/internal/channel-route-dispatch.ts +66 -0
  411. package/src/internal/channel-state.ts +96 -0
  412. package/src/internal/cli-ax.ts +111 -3
  413. package/src/internal/cli-cursor.ts +4 -1
  414. package/src/internal/cli-deploy.ts +50 -10
  415. package/src/internal/cli-mcp-oauth.ts +18 -0
  416. package/src/internal/cli-mcp.ts +11 -0
  417. package/src/internal/cli-slack.ts +15 -2
  418. package/src/internal/continuation-channel.ts +2 -1
  419. package/src/internal/continuation-identity.ts +10 -2
  420. package/src/internal/cursor/credentials.ts +35 -7
  421. package/src/internal/deploy-client.ts +54 -0
  422. package/src/internal/deploy-manifest.ts +115 -1
  423. package/src/internal/describe-error.ts +28 -0
  424. package/src/internal/discovery/agent.ts +1 -7
  425. package/src/internal/discovery/extension-overlay.ts +0 -18
  426. package/src/internal/discovery/extensions.ts +2 -26
  427. package/src/internal/discovery/info.ts +3 -13
  428. package/src/internal/discovery/modules.ts +0 -1
  429. package/src/internal/discovery/project.ts +0 -16
  430. package/src/internal/eval-runner.ts +0 -1
  431. package/src/internal/framework-file-storage.ts +4 -5
  432. package/src/internal/framework-storage-selection.ts +2 -2
  433. package/src/internal/guest-network.ts +43 -29
  434. package/src/internal/hosted-admission-adapter.ts +2 -0
  435. package/src/internal/hosted-catch-protocol.ts +130 -0
  436. package/src/internal/hosted-catch.ts +192 -0
  437. package/src/internal/hosted-delivery-protocol.ts +387 -0
  438. package/src/internal/hosted-delivery.ts +155 -22
  439. package/src/internal/hosted-execution-diag.ts +21 -3
  440. package/src/internal/hosted-execution-flush.ts +6 -3
  441. package/src/internal/http-control-plane-session.ts +104 -0
  442. package/src/internal/init-scaffold.ts +1 -2
  443. package/src/internal/install-cursor-skills.ts +38 -5
  444. package/src/internal/legacy-command-guard.ts +59 -0
  445. package/src/internal/platform-timers.ts +191 -0
  446. package/src/internal/reminder-control-plane-protocol.ts +15 -2
  447. package/src/internal/reminder-runner.ts +60 -9
  448. package/src/internal/resolve-prod-target.ts +15 -0
  449. package/src/internal/run-client.ts +1 -1
  450. package/src/internal/sdk-runner.ts +3 -2
  451. package/src/internal/server.ts +89 -95
  452. package/src/internal/session-engine.ts +155 -285
  453. package/src/internal/storage-coordinator.ts +5 -76
  454. package/src/internal/storage-roles.ts +4 -9
  455. package/src/storage-backends/cursor-hosted-v2.ts +4 -7
  456. package/src/storage-backends/cursor-hosted.ts +40 -38
  457. package/src/storage-backends/file-kv.ts +10 -51
  458. package/src/storage-protocol.ts +3 -17
  459. package/src/storage.ts +10 -101
  460. package/src/types.ts +58 -62
  461. package/templates/demo/README.md +10 -6
  462. package/templates/demo/agent/channels/github.ts +2 -0
  463. package/templates/demo/agent/channels/queue.ts +6 -2
  464. package/templates/demo/agent/lib/repos.ts +5 -0
  465. package/templates/demo/init.json +25 -0
  466. package/dist/ab.d.ts +0 -209
  467. package/dist/ab.d.ts.map +0 -1
  468. package/dist/ab.js +0 -246
  469. package/dist/docs/ab.html +0 -80
  470. package/dist/docs/ab.md +0 -332
  471. package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
  472. package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
  473. package/dist/docs/assets/chunks/@localSearchIndexroot.DXXZxiMv.js +0 -1
  474. package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
  475. package/dist/docs/assets/evals.md.CbMoebP1.js +0 -85
  476. package/dist/docs/assets/evals.md.CbMoebP1.lean.js +0 -1
  477. package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +0 -9
  478. package/dist/docs/assets/index.md.BW_6tOgR.js +0 -5
  479. package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
  480. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
  481. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
  482. package/dist/docs/assets/skills_evals.md.723kpUmA.js +0 -25
  483. package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +0 -1
  484. package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +0 -1
  485. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
  486. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
  487. package/dist/docs/assets/troubleshooting.md.Cus_YZga.js +0 -1
  488. package/dist/docs/skills/ab.html +0 -52
  489. package/dist/docs/skills/ab.md +0 -50
  490. package/dist/internal/ab-collector.d.ts +0 -44
  491. package/dist/internal/ab-collector.d.ts.map +0 -1
  492. package/dist/internal/ab-collector.js +0 -142
  493. package/dist/internal/ab-fold.d.ts +0 -36
  494. package/dist/internal/ab-fold.d.ts.map +0 -1
  495. package/dist/internal/ab-fold.js +0 -175
  496. package/dist/internal/ab-snapshot.d.ts +0 -68
  497. package/dist/internal/ab-snapshot.d.ts.map +0 -1
  498. package/dist/internal/ab-snapshot.js +0 -208
  499. package/dist/internal/discovery/ab.d.ts +0 -9
  500. package/dist/internal/discovery/ab.d.ts.map +0 -1
  501. package/dist/internal/discovery/ab.js +0 -113
  502. package/dist/playground/assets/index-Bq2HpEQB.js +0 -67
  503. package/dist/playground/assets/index-CZKKNlmb.css +0 -1
  504. package/docs/ab.md +0 -337
  505. package/skills/ab/SKILL.md +0 -58
  506. package/src/ab.ts +0 -430
  507. package/src/internal/ab-collector.ts +0 -200
  508. package/src/internal/ab-fold.ts +0 -232
  509. package/src/internal/ab-snapshot.ts +0 -331
  510. package/src/internal/discovery/ab.ts +0 -131
  511. /package/dist/docs/assets/{concepts.md.DgEcZOfT.lean.js → concepts.md.B4o63Gul.lean.js} +0 -0
  512. /package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.lean.js → guides_grokbot-agents.md.DyV-WArv.lean.js} +0 -0
  513. /package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.CJK484ex.lean.js} +0 -0
  514. /package/dist/docs/assets/{hillclimbing.md.CpTGTCle.lean.js → hillclimbing.md.BOiVo1tf.lean.js} +0 -0
  515. /package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.lean.js → reference_agent-config.md.CvoL6pof.lean.js} +0 -0
  516. /package/dist/docs/assets/{reference_connections.md.Di6jJAXF.lean.js → reference_connections.md.BojkC6c5.lean.js} +0 -0
  517. /package/dist/docs/assets/{reference_extensions.md.CGmMLblt.lean.js → reference_extensions.md.ZAVUyuEX.lean.js} +0 -0
  518. /package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.BwaCo-VO.lean.js} +0 -0
  519. /package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.CyXV1MUw.lean.js} +0 -0
  520. /package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.lean.js → scaffolding-agents.md.Kctn3OVb.lean.js} +0 -0
  521. /package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.lean.js → skills_create-agent.md.Q3h6Je-e.lean.js} +0 -0
  522. /package/dist/docs/assets/{skills_github.md.D0JahM8c.lean.js → skills_github.md.hgFX_oKY.lean.js} +0 -0
  523. /package/dist/docs/assets/{troubleshooting.md.Cus_YZga.lean.js → troubleshooting.md.CYEAO9bM.lean.js} +0 -0
@@ -12,12 +12,6 @@ import { mkdir, rm, writeFile } from "node:fs/promises";
12
12
  import { dirname, join } from "node:path";
13
13
  import type { SDKCustomTool, SDKCustomToolResult } from "@cursor/sdk";
14
14
  import type { Meter } from "@opentelemetry/api";
15
- import {
16
- type ABDefinition,
17
- mergeABInstructions,
18
- resolveABMaxPlaygroundSessions,
19
- resolveABSplit,
20
- } from "../ab.js";
21
15
  import { SLACK_CHANNEL_ID } from "../channels/slack/constants.js";
22
16
  import { materializeSlackNudgeCarrier } from "../channels/slack/nudge-carrier.js";
23
17
  import {
@@ -98,9 +92,6 @@ import {
98
92
  type ToolNeedsApproval,
99
93
  type TurnOutcome,
100
94
  } from "../types.js";
101
- import { ABCollector } from "./ab-collector.js";
102
- import { foldABStream } from "./ab-fold.js";
103
- import { type ABSnapshot, buildABSnapshot } from "./ab-snapshot.js";
104
95
  import {
105
96
  type AdvertiseHostMcp,
106
97
  resolveAdvertisedTools,
@@ -114,6 +105,10 @@ import {
114
105
  sessionClock,
115
106
  } from "./as-of.js";
116
107
  import { SessionAuthError, samePrincipal } from "./auth.js";
108
+ import {
109
+ mergeChannelStateMutation,
110
+ mergeChannelStateSkipNull,
111
+ } from "./channel-state.js";
117
112
  import { mergeCloudOptions, resolveSessionRuntime } from "./cloud-merge.js";
118
113
  import {
119
114
  applyCloudUsageToEvents,
@@ -132,7 +127,7 @@ import {
132
127
  resolveV2Key,
133
128
  V2EngineError,
134
129
  } from "./continuation-identity.js";
135
- import { describeError } from "./describe-error.js";
130
+ import { describeError, describeErrorCode } from "./describe-error.js";
136
131
  import { isDevMode } from "./dev-mode.js";
137
132
  import { type EventLogMemoryStats, EventLogStore } from "./event-log.js";
138
133
  import { TurnEventMapper } from "./event-mapper.js";
@@ -160,6 +155,7 @@ import {
160
155
  HostedAdmissionLocalSendError,
161
156
  isDuringHostedAdmission,
162
157
  } from "./hosted-admission-context.js";
158
+ import { hostedSessionResumeKey } from "./hosted-catch-protocol.js";
163
159
  import {
164
160
  formatContinuationToken,
165
161
  newContinuationKey,
@@ -217,11 +213,17 @@ import {
217
213
  } from "./workspace-sync.js";
218
214
 
219
215
  export const HTTP_CHANNEL_ID = "http";
216
+ export { mergeChannelStateSkipNull } from "./channel-state.js";
220
217
  export { SCHEDULE_CHANNEL_PREFIX } from "./prompt-context.js";
221
218
 
222
219
  /** Authored surfaces mirrored onto the Agent Store before a first cloud prompt. */
223
220
  type CloudSyncSurface = "skills" | "workspace";
224
221
 
222
+ interface EventDispatchContext {
223
+ channelState: JsonValue;
224
+ session: SessionInfo;
225
+ }
226
+
225
227
  /** The Agent Store cloud turns read authored files from, and where the VM mounts it. */
226
228
  interface CloudStoreTarget {
227
229
  sink: FileSink;
@@ -444,8 +446,8 @@ export class SessionEngine {
444
446
  /**
445
447
  * Runtime for `agent/storage.ts` (`defineStorage`), when
446
448
  * authored. All durable state changes funnel through it (session
447
- * records, event chunks, A/B samples/snapshots); the eval run store
448
- * attaches via {@link StorageCoordinator.evalRuns} at serve start.
449
+ * records, event chunks); the eval run store attaches via
450
+ * {@link StorageCoordinator.evalRuns} at serve start.
449
451
  */
450
452
  readonly storage: StorageCoordinator | undefined;
451
453
  /** In-flight lazy restores, deduped per channel + continuation key. */
@@ -453,8 +455,6 @@ export class SessionEngine {
453
455
  string,
454
456
  Promise<SessionRecord | undefined>
455
457
  >();
456
- /** Once-per-process cache for the A/B snapshot backfill (see abSnapshot). */
457
- private restoredAbSnapshot: Promise<ABSnapshot | undefined> | undefined;
458
458
  /** In-flight authored files → Agent Store syncs (see syncToCloudStore). */
459
459
  private readonly cloudSyncs = new Map<CloudSyncSurface, Promise<boolean>>();
460
460
 
@@ -517,7 +517,6 @@ export class SessionEngine {
517
517
  private probeCursorAccount:
518
518
  | ((connection: string) => Promise<string | undefined>)
519
519
  | undefined;
520
- private readonly abCollector: ABCollector;
521
520
  private readonly otel: OtelCollector | undefined;
522
521
  private readonly otelHost: HostOtelSessionApi;
523
522
  private readonly stopMemoryTelemetry: (() => void) | undefined;
@@ -628,13 +627,6 @@ export class SessionEngine {
628
627
  config: options.project.artifacts,
629
628
  sink: managedV2Files?.(),
630
629
  });
631
- this.abCollector = new ABCollector(
632
- options.project.abs,
633
- this.logger,
634
- async (sessionId) => (await this.logs.get(sessionId)).snapshot(0),
635
- // Samples flow to the defineStorage `abs` table (no-op without one).
636
- { persistSample: (sample) => this.storage?.abSample(sample) }
637
- );
638
630
  // Peer and Cursor-account transports are symbolic until the serve host
639
631
  // resolves them; the host-side MCP registry starts with the concrete
640
632
  // connections and gains the rest via setResolvedConnections.
@@ -1019,6 +1011,18 @@ export class SessionEngine {
1019
1011
  sendOptions.continuationToken
1020
1012
  );
1021
1013
  }
1014
+ if (
1015
+ existing === undefined &&
1016
+ sendOptions.hostedSessionId !== undefined &&
1017
+ sendOptions.mailboxContinuation?.key ===
1018
+ hostedSessionResumeKey(sendOptions.hostedSessionId)
1019
+ ) {
1020
+ // Explicit control-plane resume of an existing session: the CP named
1021
+ // the session by its own id and stamped the matching resume key. The
1022
+ // session keeps its original continuation key (a PR lane must stay
1023
+ // addressable by its webhooks); this is a follow-up turn by id.
1024
+ existing = await this.getOrRestoreSession(sendOptions.hostedSessionId);
1025
+ }
1022
1026
 
1023
1027
  if (existing !== undefined) {
1024
1028
  if (
@@ -1115,7 +1119,7 @@ export class SessionEngine {
1115
1119
  const purpose = sendOptions.purpose === "eval" ? "eval" : "live";
1116
1120
  const frozenAsOf = normalizeAsOf(sendOptions.asOf);
1117
1121
  assertTimeArgs(this.project.agent.tools, frozenAsOf);
1118
- let record: SessionRecord = {
1122
+ const record: SessionRecord = {
1119
1123
  sessionId: sendOptions.hostedSessionId ?? newSessionId(),
1120
1124
  channelId,
1121
1125
  mode: sendOptions.mode ?? "chat",
@@ -1144,7 +1148,6 @@ export class SessionEngine {
1144
1148
  dryRun: record.dryRun === true ? true : undefined,
1145
1149
  },
1146
1150
  });
1147
- record = await this.enrollABs(record);
1148
1151
  const since = (await this.logs.get(record.sessionId)).count;
1149
1152
  await this.startTurn(record.sessionId, message, {
1150
1153
  admission: sendOptions.admission ?? "preempt",
@@ -1218,97 +1221,6 @@ export class SessionEngine {
1218
1221
  return existing !== undefined;
1219
1222
  }
1220
1223
 
1221
- /**
1222
- * Sticky A/B enrollment at session creation — before the first turn, so
1223
- * variants are in the durable stream (and on {@link SessionRecord.abs})
1224
- * ahead of model/instructions work. Failures persist as `variant: null`
1225
- * (sticky skip). Eval harness sessions (`purpose: "eval"`) are never
1226
- * enrolled.
1227
- */
1228
- private async enrollABs(record: SessionRecord): Promise<SessionRecord> {
1229
- if (!this.abCollector.enabled || record.purpose === "eval") {
1230
- return record;
1231
- }
1232
- const sessionInfo = this.sessionInfo(record);
1233
- const abs: Record<string, string | null> = {};
1234
- for (const experiment of this.project.abs) {
1235
- const def = experiment.definition as ABDefinition;
1236
- const variantKeys = Object.keys(def.variants);
1237
- let variant: string | null = null;
1238
- try {
1239
- variant = await resolveABSplit(def.split, {
1240
- agent: { name: this.project.name },
1241
- channel: { id: record.channelId },
1242
- session: sessionInfo,
1243
- experiment: experiment.name,
1244
- variants: variantKeys,
1245
- });
1246
- if (variant !== null && !(variant in def.variants)) {
1247
- throw new Error(
1248
- `split resolved to ${JSON.stringify(variant)}; expected one of ${variantKeys.join(", ")} or null to skip`
1249
- );
1250
- }
1251
- } catch (error) {
1252
- this.logger(
1253
- `[agent-sdk] ab "${experiment.name}" enrollment failed (sticky skip): ${describeError(error)}`
1254
- );
1255
- variant = null;
1256
- }
1257
- abs[experiment.name] = variant;
1258
- await this.appendEvent(record.sessionId, {
1259
- type: "ab.assigned",
1260
- data: { experiment: experiment.name, variant },
1261
- });
1262
- }
1263
- return this.updateRecord(record.sessionId, (current) => ({
1264
- ...current,
1265
- abs,
1266
- }));
1267
- }
1268
-
1269
- /**
1270
- * Ensure {@link SessionRecord.abs} is populated (hydrate from the durable
1271
- * `ab.assigned` stream when missing — e.g. older sessions after upgrade).
1272
- */
1273
- private async ensureAbs(record: SessionRecord): Promise<SessionRecord> {
1274
- if (record.abs !== undefined || record.purpose === "eval") {
1275
- return record;
1276
- }
1277
- if (!this.abCollector.enabled) {
1278
- return record;
1279
- }
1280
- const events = await this.listEvents(record.sessionId, 0);
1281
- const folded = foldABStream(events);
1282
- if (folded.arms.size === 0) {
1283
- return record;
1284
- }
1285
- const abs = Object.fromEntries(folded.arms);
1286
- return this.updateRecord(record.sessionId, (current) => ({
1287
- ...current,
1288
- abs,
1289
- }));
1290
- }
1291
-
1292
- /**
1293
- * Agent config for this session: base project agent plus any per-variant
1294
- * `instructions` overlays from enrolled A/B arms.
1295
- */
1296
- private agentForSession(record: SessionRecord): ResolvedAgent {
1297
- const base = this.project.agent;
1298
- const instructions = mergeABInstructions(
1299
- base.instructions,
1300
- record.abs,
1301
- this.project.abs.map((experiment) => ({
1302
- name: experiment.name,
1303
- definition: experiment.definition as ABDefinition,
1304
- }))
1305
- );
1306
- if (instructions === base.instructions) {
1307
- return base;
1308
- }
1309
- return { ...base, instructions };
1310
- }
1311
-
1312
1224
  /** Look up a session as a channel-scoped handle. */
1313
1225
  async getChannelSession(
1314
1226
  channelId: string,
@@ -1633,12 +1545,10 @@ export class SessionEngine {
1633
1545
 
1634
1546
  let lifecycleInstalled = false;
1635
1547
  try {
1636
- let record = await this.updateRecord(sessionId, (current) => ({
1548
+ const record = await this.updateRecord(sessionId, (current) => ({
1637
1549
  ...current,
1638
1550
  turnCount: current.turnCount + 1,
1639
1551
  }));
1640
- // Arms must be on the record before tools/instructions see SessionInfo.
1641
- record = await this.ensureAbs(record);
1642
1552
  const turnId = `turn_${record.turnCount}`;
1643
1553
  const isFirstTurn = record.turnCount === 1;
1644
1554
 
@@ -1668,10 +1578,16 @@ export class SessionEngine {
1668
1578
  isFirstTurn,
1669
1579
  abort.signal
1670
1580
  );
1581
+ if (outcome.status === "cancelled") {
1582
+ outcome.cancellationReason = abort.signal.aborted
1583
+ ? "signal"
1584
+ : "runner";
1585
+ }
1671
1586
  } catch (error) {
1672
1587
  outcome = {
1673
1588
  status: "error",
1674
1589
  errorMessage: describeError(error),
1590
+ errorCode: describeErrorCode(error),
1675
1591
  };
1676
1592
  } finally {
1677
1593
  clearInterval(poll);
@@ -2192,6 +2108,11 @@ export class SessionEngine {
2192
2108
  const sessionId = record.sessionId;
2193
2109
  const workspaceDir = this.scaffoldDir(record);
2194
2110
  const harnessCwd = this.harnessCwd(record);
2111
+ const turnChannelState = structuredClone(record.channelState ?? null);
2112
+ const eventContext: EventDispatchContext = {
2113
+ channelState: structuredClone(turnChannelState),
2114
+ session: this.sessionInfo(record),
2115
+ };
2195
2116
  // Hold the open log so tool events append synchronously. Fire-and-forget
2196
2117
  // `appendEvent` races parallel tool completions and delays the live stream
2197
2118
  // until the next await tick — often after *all* parallel tools finish.
@@ -2199,7 +2120,7 @@ export class SessionEngine {
2199
2120
  const emit = (payload: SessionEventPayload): void => {
2200
2121
  try {
2201
2122
  const event = log.append({ ...payload, turnId });
2202
- this.queueDispatch(sessionId, event);
2123
+ this.queueDispatch(sessionId, event, eventContext);
2203
2124
  } catch (error) {
2204
2125
  this.logger(
2205
2126
  `[agent-sdk] failed to record event for ${sessionId}: ${describeError(error)}`
@@ -2235,12 +2156,10 @@ export class SessionEngine {
2235
2156
  emit({ type: "turn.started", data: {} });
2236
2157
  try {
2237
2158
  // Scaffold agent files into the session workspace even when the harness
2238
- // cwd is overridden (e.g. a PR worktree). A/B variant instruction
2239
- // overlays are applied via agentForSession.
2240
- const agent = this.agentForSession(record);
2159
+ // cwd is overridden (e.g. a PR worktree).
2241
2160
  if (!this.hasRootOverride()) {
2242
2161
  await materializeWorkspace({
2243
- agent,
2162
+ agent: this.project.agent,
2244
2163
  workspaceDir,
2245
2164
  seed: isFirstTurn,
2246
2165
  stateRoot: this.stateRoot,
@@ -2262,7 +2181,7 @@ export class SessionEngine {
2262
2181
  const pendingFiles = record.pendingWorkspaceFiles;
2263
2182
  const pendingImages = record.pendingImages;
2264
2183
  const runtime = resolveSessionRuntime({
2265
- agentRuntime: agent.runtime,
2184
+ agentRuntime: this.project.agent.runtime,
2266
2185
  cloudOverride: record.cloudOverride,
2267
2186
  });
2268
2187
  const hasPendingFiles =
@@ -2305,12 +2224,12 @@ export class SessionEngine {
2305
2224
  (await isNestedInGitRepo(harnessCwd)));
2306
2225
  const request = await this.buildTurnRequest(
2307
2226
  record,
2308
- agent,
2309
2227
  turnId,
2310
2228
  message,
2311
2229
  isFirstTurn,
2312
2230
  instructionsInvisibleToHarness,
2313
2231
  emit,
2232
+ eventContext,
2314
2233
  async (update) => {
2315
2234
  const turn = this.turnRoots.get(sessionId);
2316
2235
  if (turn !== undefined) {
@@ -2352,7 +2271,11 @@ export class SessionEngine {
2352
2271
  } catch (error) {
2353
2272
  this.approvals.cancelSession(sessionId, "deny");
2354
2273
  this.auths.cancelSession(sessionId, "deny");
2355
- outcome = { status: "error", errorMessage: describeError(error) };
2274
+ outcome = {
2275
+ status: "error",
2276
+ errorMessage: describeError(error),
2277
+ errorCode: describeErrorCode(error),
2278
+ };
2356
2279
  } finally {
2357
2280
  permit.release();
2358
2281
  this.dropTurnFileSystem(sessionId);
@@ -2371,6 +2294,7 @@ export class SessionEngine {
2371
2294
  if (mapper.title !== undefined) {
2372
2295
  const title = mapper.title;
2373
2296
  await this.updateRecord(sessionId, (current) => ({ ...current, title }));
2297
+ eventContext.session = { ...eventContext.session, title };
2374
2298
  }
2375
2299
 
2376
2300
  const finalResult = outcome.result ?? mapper.finalText;
@@ -2395,7 +2319,8 @@ export class SessionEngine {
2395
2319
  text: finalResult,
2396
2320
  dryRun: record.dryRun === true,
2397
2321
  ctx: {
2398
- session: this.sessionInfo(record),
2322
+ session: eventContext.session,
2323
+ channelState: turnChannelState,
2399
2324
  host: this.hostForSession(sessionId),
2400
2325
  artifacts: this.artifactsApi({ sessionId, turnId }),
2401
2326
  stateRoot: this.stateRoot,
@@ -2414,29 +2339,38 @@ export class SessionEngine {
2414
2339
  }
2415
2340
 
2416
2341
  if (outcome.status === "finished") {
2417
- await this.appendEvent(sessionId, {
2418
- type: "turn.completed",
2419
- turnId,
2420
- data: {
2421
- result: finalResult,
2422
- usage: finalUsage,
2423
- cost: finalCost,
2342
+ await this.appendEvent(
2343
+ sessionId,
2344
+ {
2345
+ type: "turn.completed",
2346
+ turnId,
2347
+ data: {
2348
+ result: finalResult,
2349
+ usage: finalUsage,
2350
+ cost: finalCost,
2351
+ },
2424
2352
  },
2425
- });
2353
+ eventContext
2354
+ );
2426
2355
  } else {
2427
2356
  const interrupted = signal.aborted && outcome.status === "cancelled";
2428
- await this.appendEvent(sessionId, {
2429
- type: "turn.failed",
2430
- turnId,
2431
- data: {
2432
- message: interrupted
2433
- ? "turn interrupted"
2434
- : (outcome.errorMessage ??
2435
- (outcome.status === "cancelled"
2436
- ? "turn cancelled"
2437
- : "turn failed")),
2357
+ await this.appendEvent(
2358
+ sessionId,
2359
+ {
2360
+ type: "turn.failed",
2361
+ turnId,
2362
+ data: {
2363
+ status: outcome.status,
2364
+ message: interrupted
2365
+ ? "turn interrupted"
2366
+ : (outcome.errorMessage ??
2367
+ (outcome.status === "cancelled"
2368
+ ? "turn cancelled"
2369
+ : "turn failed")),
2370
+ },
2438
2371
  },
2439
- });
2372
+ eventContext
2373
+ );
2440
2374
  }
2441
2375
 
2442
2376
  const current = await this.sessions.get(sessionId);
@@ -2450,15 +2384,20 @@ export class SessionEngine {
2450
2384
  type: "session.failed",
2451
2385
  turnId,
2452
2386
  data: { message: outcome.errorMessage ?? "task failed" },
2453
- }
2387
+ },
2388
+ eventContext
2454
2389
  );
2455
2390
  await this.wipeCloudSessionWorkspace(sessionId);
2456
2391
  } else {
2457
- await this.appendEvent(sessionId, {
2458
- type: "session.waiting",
2459
- turnId,
2460
- data: {},
2461
- });
2392
+ await this.appendEvent(
2393
+ sessionId,
2394
+ {
2395
+ type: "session.waiting",
2396
+ turnId,
2397
+ data: {},
2398
+ },
2399
+ eventContext
2400
+ );
2462
2401
  }
2463
2402
 
2464
2403
  return {
@@ -2658,16 +2597,17 @@ export class SessionEngine {
2658
2597
 
2659
2598
  private async buildTurnRequest(
2660
2599
  record: SessionRecord,
2661
- agent: ResolvedAgent,
2662
2600
  turnId: string,
2663
2601
  prompt: string,
2664
2602
  isFirstTurn: boolean,
2665
2603
  instructionsInvisibleToHarness: boolean,
2666
2604
  emit: (payload: SessionEventPayload) => void,
2605
+ eventContext: EventDispatchContext,
2667
2606
  onUpdate: RunnerTurnRequest["onUpdate"],
2668
2607
  signal: AbortSignal,
2669
2608
  images?: Array<{ data: string; mimeType: string }>
2670
2609
  ): Promise<RunnerTurnRequest> {
2610
+ const agent = this.project.agent;
2671
2611
  // Per-session cloud attach (channel/tool handoff) forces cloud runtime
2672
2612
  // even when the agent defaults to local for chat server tools.
2673
2613
  const runtime = resolveSessionRuntime({
@@ -2875,9 +2815,7 @@ export class SessionEngine {
2875
2815
  ? {}
2876
2816
  : { sdkAgentId: record.sdkAgentId }),
2877
2817
  workspaceDir: this.harnessCwd(record),
2878
- sandbox: authoredRoot
2879
- ? false
2880
- : this.project.agent.local?.sandbox === true,
2818
+ sandbox: authoredRoot ? false : agent.local?.sandbox === true,
2881
2819
  ...(runtime === "local" && harnessTools !== undefined
2882
2820
  ? {
2883
2821
  ...(harnessTools.tools === undefined
@@ -2910,13 +2848,7 @@ export class SessionEngine {
2910
2848
  : {}),
2911
2849
  customTools:
2912
2850
  runtime === "local"
2913
- ? await this.buildCustomTools(
2914
- record,
2915
- agent,
2916
- turnId,
2917
- emit,
2918
- synthesized
2919
- )
2851
+ ? await this.buildCustomTools(record, turnId, emit, synthesized)
2920
2852
  : {},
2921
2853
  mcpServers: this.buildMcpServers(
2922
2854
  runtime,
@@ -2944,16 +2876,21 @@ export class SessionEngine {
2944
2876
  sdkAgentId,
2945
2877
  }));
2946
2878
  record.sdkAgentId = sdkAgentId;
2947
- await this.appendEvent(record.sessionId, {
2948
- type: "agent.bound",
2949
- turnId,
2950
- data: {
2951
- sdkAgentId,
2952
- ...(sdkAgentId.startsWith("bc-")
2953
- ? { url: `https://cursor.com/agents/${sdkAgentId}` }
2954
- : {}),
2879
+ eventContext.session = { ...eventContext.session, sdkAgentId };
2880
+ await this.appendEvent(
2881
+ record.sessionId,
2882
+ {
2883
+ type: "agent.bound",
2884
+ turnId,
2885
+ data: {
2886
+ sdkAgentId,
2887
+ ...(sdkAgentId.startsWith("bc-")
2888
+ ? { url: `https://cursor.com/agents/${sdkAgentId}` }
2889
+ : {}),
2890
+ },
2955
2891
  },
2956
- });
2892
+ eventContext
2893
+ );
2957
2894
  },
2958
2895
  };
2959
2896
  }
@@ -3208,11 +3145,11 @@ export class SessionEngine {
3208
3145
 
3209
3146
  private async buildCustomTools(
3210
3147
  record: SessionRecord,
3211
- agent: ResolvedAgent,
3212
3148
  turnId: string,
3213
3149
  emit: (payload: SessionEventPayload) => void,
3214
3150
  extraTools: DiscoveredTool[] = []
3215
3151
  ): Promise<Record<string, SDKCustomTool>> {
3152
+ const agent = this.project.agent;
3216
3153
  const tools: Record<string, SDKCustomTool> = {};
3217
3154
  const register = (tool: ResolvedAgent["tools"][number]): void => {
3218
3155
  tools[tool.name] = {
@@ -4606,21 +4543,26 @@ export class SessionEngine {
4606
4543
 
4607
4544
  private async appendEvent(
4608
4545
  sessionId: string,
4609
- payload: SessionEventPayload & { turnId?: string }
4546
+ payload: SessionEventPayload & { turnId?: string },
4547
+ context?: EventDispatchContext
4610
4548
  ): Promise<SessionEvent> {
4611
4549
  const log = await this.logs.get(sessionId);
4612
4550
  const event = log.append(payload);
4613
- this.queueDispatch(sessionId, event);
4551
+ this.queueDispatch(sessionId, event, context);
4614
4552
  return event;
4615
4553
  }
4616
4554
 
4617
- private queueDispatch(sessionId: string, event: SessionEvent): void {
4555
+ private queueDispatch(
4556
+ sessionId: string,
4557
+ event: SessionEvent,
4558
+ context?: EventDispatchContext
4559
+ ): void {
4618
4560
  // Single funnel for both append paths (appendEvent + the held-log emit),
4619
4561
  // so the storage sink sees every durable event exactly once.
4620
4562
  this.storage?.event(event);
4621
4563
  const chain = this.dispatchChains.get(sessionId) ?? Promise.resolve();
4622
4564
  const next = chain
4623
- .then(() => this.dispatchEvent(sessionId, event))
4565
+ .then(() => this.dispatchEvent(sessionId, event, context))
4624
4566
  .catch((error) => {
4625
4567
  this.logger(
4626
4568
  `[agent-sdk] event dispatch failed for ${sessionId}: ${describeError(error)}`
@@ -4637,16 +4579,27 @@ export class SessionEngine {
4637
4579
 
4638
4580
  private async dispatchEvent(
4639
4581
  sessionId: string,
4640
- event: SessionEvent
4582
+ event: SessionEvent,
4583
+ context?: EventDispatchContext
4641
4584
  ): Promise<void> {
4642
4585
  const record = await this.sessions.get(sessionId);
4643
4586
  if (record === undefined) {
4644
4587
  return;
4645
4588
  }
4589
+ const channelState =
4590
+ context === undefined
4591
+ ? (record.channelState ?? null)
4592
+ : context.channelState;
4593
+ const channelStateBefore =
4594
+ context === undefined ? undefined : structuredClone(channelState);
4646
4595
 
4647
4596
  const sessionCtx: SessionContext = {
4648
- session: this.sessionInfo(record),
4597
+ session: context?.session ?? this.sessionInfo(record),
4649
4598
  host: this.hostForSession(record.sessionId),
4599
+ artifacts: this.artifactsApi({
4600
+ sessionId: record.sessionId,
4601
+ turnId: event.turnId,
4602
+ }),
4650
4603
  };
4651
4604
  const channelEvents = this.channelEventHandlersFor(record.channelId);
4652
4605
  if (channelEvents !== undefined) {
@@ -4658,7 +4611,7 @@ export class SessionEngine {
4658
4611
  ];
4659
4612
  const channelCtx = {
4660
4613
  channelId: record.channelId,
4661
- state: (record.channelState ?? null) as JsonValue,
4614
+ state: channelState,
4662
4615
  continuationToken: record.continuationKey,
4663
4616
  setContinuationToken: (token: string | null) =>
4664
4617
  this.setContinuationToken(sessionId, token),
@@ -4675,8 +4628,21 @@ export class SessionEngine {
4675
4628
  );
4676
4629
  }
4677
4630
  }
4678
- // Handlers mutate channel state in place; persist after each batch.
4679
- await this.updateRecord(sessionId, (current) => ({ ...current }));
4631
+ if (context === undefined || channelStateBefore === undefined) {
4632
+ // Handlers mutate live channel state in place; save the current record.
4633
+ await this.updateRecord(sessionId, (current) => ({ ...current }));
4634
+ } else {
4635
+ const updatedState = channelCtx.state as JsonValue;
4636
+ context.channelState = updatedState;
4637
+ await this.updateRecord(sessionId, (current) => ({
4638
+ ...current,
4639
+ channelState: mergeChannelStateMutation({
4640
+ current: current.channelState,
4641
+ before: channelStateBefore,
4642
+ after: updatedState,
4643
+ }),
4644
+ }));
4645
+ }
4680
4646
  }
4681
4647
 
4682
4648
  for (const hook of this.project.hooks) {
@@ -4697,10 +4663,6 @@ export class SessionEngine {
4697
4663
  continuationToken: record.continuationKey,
4698
4664
  },
4699
4665
  stateRoot: this.stateRoot,
4700
- artifacts: this.artifactsApi({
4701
- sessionId: record.sessionId,
4702
- turnId: event.turnId,
4703
- }),
4704
4666
  });
4705
4667
  } catch (error) {
4706
4668
  this.logger(
@@ -4710,14 +4672,6 @@ export class SessionEngine {
4710
4672
  }
4711
4673
  }
4712
4674
 
4713
- if (this.abCollector.enabled) {
4714
- await this.abCollector.onEvent(
4715
- event,
4716
- sessionCtx.session,
4717
- this.project.name
4718
- );
4719
- }
4720
-
4721
4675
  this.otel?.onEvent(event, sessionCtx.session);
4722
4676
  }
4723
4677
 
@@ -4776,6 +4730,10 @@ export class SessionEngine {
4776
4730
  await active;
4777
4731
  continue;
4778
4732
  }
4733
+ const dispatch = this.dispatchChains.get(sessionId);
4734
+ if (dispatch !== undefined) {
4735
+ await dispatch.catch(() => {});
4736
+ }
4779
4737
  return this.lastOutcomes.get(sessionId) ?? { status: "finished" };
4780
4738
  }
4781
4739
  }
@@ -5033,61 +4991,6 @@ export class SessionEngine {
5033
4991
  });
5034
4992
  }
5035
4993
 
5036
- /**
5037
- * Fold durable session streams into per-session A/B assignments and
5038
- * aggregate arm metrics (`GET /v1/abs`). Collector-independent: always
5039
- * reads `events.ndjson`.
5040
- */
5041
- async abSnapshot(
5042
- caller: AuthContext | null,
5043
- options?: { includeAll?: boolean }
5044
- ): Promise<ABSnapshot> {
5045
- const sessions = await this.listSessions(caller, options);
5046
- const abConfig = this.project.abConfig;
5047
- const maxPlaygroundSessions = resolveABMaxPlaygroundSessions(
5048
- abConfig?.maxPlaygroundSessions
5049
- );
5050
- const foldedSessions = sessions.slice(0, maxPlaygroundSessions);
5051
- // Backfill for a replacement host with nothing local to fold (e.g.
5052
- // lazy-only restore before any session resumed): serve the persisted
5053
- // aggregate instead of an empty surface. Gated on the host having no
5054
- // sessions AT ALL — the persisted snapshot spans every principal, so a
5055
- // caller who merely owns no sessions must not see it. Loaded once per
5056
- // process (playground polls this route ~every 4s); skip the persist
5057
- // side effect below — re-saving a restored snapshot would echo stale
5058
- // data back into the store.
5059
- if (
5060
- foldedSessions.length === 0 &&
5061
- this.storage !== undefined &&
5062
- (await this.sessions.list()).length === 0
5063
- ) {
5064
- this.restoredAbSnapshot ??= this.storage.getLatestAbSnapshot();
5065
- const restoredSnapshot = await this.restoredAbSnapshot;
5066
- if (restoredSnapshot !== undefined) {
5067
- return restoredSnapshot;
5068
- }
5069
- }
5070
- const abTable = this.project.storage?.abs;
5071
- const snapshot = await buildABSnapshot({
5072
- experiments: this.project.abs,
5073
- agentName: this.project.name,
5074
- sessions: foldedSessions,
5075
- loadRecord: (sessionId) => this.sessions.get(sessionId),
5076
- loadEvents: (sessionId) => this.listEvents(sessionId, 0),
5077
- sessionInfo: (record) => this.sessionInfo(record),
5078
- logger: this.logger,
5079
- config: {
5080
- maxPlaygroundSessions,
5081
- durableSamples: abTable !== undefined,
5082
- durableSnapshots: abTable?.putSnapshot !== undefined,
5083
- },
5084
- });
5085
- // Side effect on the read path: playground polls GET /v1/abs ~every 4s;
5086
- // the coordinator throttles the actual table write.
5087
- this.storage?.abSnapshot(snapshot);
5088
- return snapshot;
5089
- }
5090
-
5091
4994
  async eventStream(
5092
4995
  sessionId: string,
5093
4996
  startIndex = 0
@@ -5347,7 +5250,6 @@ export class SessionEngine {
5347
5250
  asOf: record.asOf,
5348
5251
  auth: record.auth,
5349
5252
  continuationKey: record.continuationKey,
5350
- ...(record.abs === undefined ? {} : { abs: record.abs }),
5351
5253
  ...(record.title === undefined ? {} : { title: record.title }),
5352
5254
  ...(record.sdkAgentId === undefined
5353
5255
  ? {}
@@ -5449,9 +5351,9 @@ export class SessionEngine {
5449
5351
  * serve start, before channels accept traffic: any persisted session
5450
5352
  * missing from the local `--state-root` is materialized there — events
5451
5353
  * as `events.ndjson`, record as `session.json` — after which every
5452
- * existing read path (continuation lookup, event replay/streams, A/B
5453
- * fold hydration) works unchanged. Local state always wins over the
5454
- * sink, so restarts on the same host are no-ops.
5354
+ * existing read path (continuation lookup, event replay/streams) works
5355
+ * unchanged. Local state always wins over the sink, so restarts on the
5356
+ * same host are no-ops.
5455
5357
  *
5456
5358
  * Failures are logged and skipped; a broken store (including rows that
5457
5359
  * violate the SessionRecord shape) never blocks serve start.
@@ -5770,38 +5672,6 @@ function mergePendingWorkspaceFiles(
5770
5672
  return { ...current, ...incoming };
5771
5673
  }
5772
5674
 
5773
- /**
5774
- * Shallow-merge a wake patch into durable channel state. Null / undefined
5775
- * patch values leave the existing key alone so sticky fields survive.
5776
- */
5777
- export function mergeChannelStateSkipNull(
5778
- current: JsonValue | undefined,
5779
- patch: JsonValue | undefined
5780
- ): JsonValue | undefined {
5781
- if (patch === undefined) {
5782
- return current;
5783
- }
5784
- if (
5785
- typeof patch !== "object" ||
5786
- patch === null ||
5787
- Array.isArray(patch) ||
5788
- typeof current !== "object" ||
5789
- current === null ||
5790
- Array.isArray(current)
5791
- ) {
5792
- return structuredClone(patch);
5793
- }
5794
- const merged: Record<string, JsonValue> = {
5795
- ...(current as Record<string, JsonValue>),
5796
- };
5797
- for (const [key, value] of Object.entries(patch)) {
5798
- if (value !== null && value !== undefined) {
5799
- merged[key] = value as JsonValue;
5800
- }
5801
- }
5802
- return merged;
5803
- }
5804
-
5805
5675
  function eventsNdjson(events: SessionEvent[]): string | undefined {
5806
5676
  if (events.length === 0) {
5807
5677
  return undefined;