@cursor/july 0.1.107 → 0.1.108

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 (302) hide show
  1. package/README.md +10 -5
  2. package/dist/bin/agent-serve.js +30 -8
  3. package/dist/channels/github/github-channel.js +8 -5
  4. package/dist/channels/github/types.d.ts +5 -1
  5. package/dist/channels/github/types.d.ts.map +1 -1
  6. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  7. package/dist/channels/origin/origin-channel.js +27 -13
  8. package/dist/channels/origin/types.d.ts +5 -1
  9. package/dist/channels/origin/types.d.ts.map +1 -1
  10. package/dist/channels.d.ts +45 -0
  11. package/dist/channels.d.ts.map +1 -1
  12. package/dist/channels.js +106 -7
  13. package/dist/connections.d.ts +2 -1
  14. package/dist/connections.d.ts.map +1 -1
  15. package/dist/connections.js +2 -1
  16. package/dist/docs/404.html +2 -2
  17. package/dist/docs/ab.html +4 -4
  18. package/dist/docs/assets/{app.CtuckIiL.js → app.BASKM3M4.js} +1 -1
  19. package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +1 -0
  20. package/dist/docs/assets/chunks/{VPLocalSearchBox.Bkkhnu8K.js → VPLocalSearchBox.BOKxlYGP.js} +1 -1
  21. package/dist/docs/assets/chunks/{theme.DhpIe0Pa.js → theme.DbDZW-zb.js} +2 -2
  22. package/dist/docs/assets/{deployment.md.MFPKqsqI.js → deployment.md.JenwuCCB.js} +4 -4
  23. package/dist/docs/assets/{deployment.md.MFPKqsqI.lean.js → deployment.md.JenwuCCB.lean.js} +1 -1
  24. package/dist/docs/assets/{evals.md.CbMoebP1.js → evals.md.C1ekS3k2.js} +1 -1
  25. package/dist/docs/assets/guides_cloud-agents.md.BsloyHdY.js +9 -0
  26. package/dist/docs/assets/{guides_cloud-agents.md.DS8RIjwx.lean.js → guides_cloud-agents.md.BsloyHdY.lean.js} +1 -1
  27. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.js → guides_github.md.BH33UEBJ.js} +1 -1
  28. package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.js → guides_grokbot-agents.md.DyV-WArv.js} +1 -1
  29. package/dist/docs/assets/guides_improve.md.BGVk32bK.js +14 -0
  30. package/dist/docs/assets/guides_improve.md.BGVk32bK.lean.js +1 -0
  31. package/dist/docs/assets/{guides_slack.md.9oHPye9o.js → guides_slack.md.D4RVMM4G.js} +3 -3
  32. package/dist/docs/assets/{guides_slack.md.9oHPye9o.lean.js → guides_slack.md.D4RVMM4G.lean.js} +1 -1
  33. package/dist/docs/assets/index.md.BjH1w2ZW.js +5 -0
  34. package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.js → reference_agent-config.md.CvoL6pof.js} +1 -1
  35. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.js → reference_cli.md.Ca26u0Es.js} +6 -6
  36. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.lean.js → reference_cli.md.Ca26u0Es.lean.js} +1 -1
  37. package/dist/docs/assets/{reference_connections.md.Di6jJAXF.js → reference_connections.md.BojkC6c5.js} +1 -1
  38. package/dist/docs/assets/{reference_extensions.md.CGmMLblt.js → reference_extensions.md.CPWt00ds.js} +1 -1
  39. package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.js → scaffolding-agents.md.Kctn3OVb.js} +1 -1
  40. package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.js → skills_create-agent.md.Q3h6Je-e.js} +1 -1
  41. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.js → skills_debug.md.CVjCXMFF.js} +1 -1
  42. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.lean.js → skills_debug.md.CVjCXMFF.lean.js} +1 -1
  43. package/dist/docs/assets/{skills_evals.md.723kpUmA.js → skills_evals.md.BhovOvrl.js} +1 -1
  44. package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.js +1 -0
  45. package/dist/docs/assets/{skills_framework-map.md.haibFyoB.lean.js → skills_framework-map.md.D-tFZhFS.lean.js} +1 -1
  46. package/dist/docs/assets/{skills_github.md.D0JahM8c.js → skills_github.md.hgFX_oKY.js} +1 -1
  47. package/dist/docs/assets/troubleshooting.md.CYEAO9bM.js +1 -0
  48. package/dist/docs/building-with-agents.html +4 -4
  49. package/dist/docs/concepts.html +4 -4
  50. package/dist/docs/deployment.html +7 -7
  51. package/dist/docs/deployment.md +7 -2
  52. package/dist/docs/evals.html +6 -6
  53. package/dist/docs/evals.md +3 -2
  54. package/dist/docs/guides/agent-to-agent.html +4 -4
  55. package/dist/docs/guides/cloud-agents.html +6 -6
  56. package/dist/docs/guides/cloud-agents.md +4 -3
  57. package/dist/docs/guides/convert-automation.html +4 -4
  58. package/dist/docs/guides/github.html +5 -5
  59. package/dist/docs/guides/github.md +2 -1
  60. package/dist/docs/guides/grokbot-agents.html +6 -6
  61. package/dist/docs/guides/grokbot-agents.md +2 -2
  62. package/dist/docs/guides/human-in-the-loop.html +4 -4
  63. package/dist/docs/guides/improve.html +40 -0
  64. package/dist/docs/guides/improve.md +91 -0
  65. package/dist/docs/guides/mcp-oauth.html +4 -4
  66. package/dist/docs/guides/opentelemetry.html +5 -5
  67. package/dist/docs/guides/slack.html +6 -6
  68. package/dist/docs/guides/slack.md +2 -1
  69. package/dist/docs/guides/webhooks.html +4 -4
  70. package/dist/docs/hashmap.json +1 -1
  71. package/dist/docs/hillclimbing.html +4 -4
  72. package/dist/docs/index.html +6 -6
  73. package/dist/docs/index.md +4 -0
  74. package/dist/docs/llms-full.txt +158 -33
  75. package/dist/docs/llms.txt +1 -0
  76. package/dist/docs/quickstart.html +4 -4
  77. package/dist/docs/reference/agent-config.html +6 -6
  78. package/dist/docs/reference/agent-config.md +5 -2
  79. package/dist/docs/reference/artifacts.html +4 -4
  80. package/dist/docs/reference/channels.html +4 -4
  81. package/dist/docs/reference/cli.html +10 -10
  82. package/dist/docs/reference/cli.md +18 -11
  83. package/dist/docs/reference/connections.html +6 -6
  84. package/dist/docs/reference/connections.md +2 -1
  85. package/dist/docs/reference/extensions.html +6 -6
  86. package/dist/docs/reference/extensions.md +2 -0
  87. package/dist/docs/reference/hooks.html +4 -4
  88. package/dist/docs/reference/http-api.html +4 -4
  89. package/dist/docs/reference/instructions.html +4 -4
  90. package/dist/docs/reference/playground.html +4 -4
  91. package/dist/docs/reference/project-layout.html +4 -4
  92. package/dist/docs/reference/prompt.html +4 -4
  93. package/dist/docs/reference/result.html +4 -4
  94. package/dist/docs/reference/schedules.html +4 -4
  95. package/dist/docs/reference/sessions.html +4 -4
  96. package/dist/docs/reference/skills.html +4 -4
  97. package/dist/docs/reference/subagents.html +4 -4
  98. package/dist/docs/reference/tools.html +4 -4
  99. package/dist/docs/scaffolding-agents.html +5 -5
  100. package/dist/docs/scaffolding-agents.md +2 -1
  101. package/dist/docs/skills/ab.html +4 -4
  102. package/dist/docs/skills/create-agent.html +6 -6
  103. package/dist/docs/skills/create-agent.md +1 -1
  104. package/dist/docs/skills/debug.html +5 -5
  105. package/dist/docs/skills/debug.md +1 -1
  106. package/dist/docs/skills/evals.html +6 -6
  107. package/dist/docs/skills/evals.md +1 -1
  108. package/dist/docs/skills/framework-map.html +5 -5
  109. package/dist/docs/skills/framework-map.md +4 -2
  110. package/dist/docs/skills/github.html +6 -6
  111. package/dist/docs/skills/github.md +1 -1
  112. package/dist/docs/skills/hillclimb.html +4 -4
  113. package/dist/docs/skills/index.html +4 -4
  114. package/dist/docs/skills/mcp-auth.html +4 -4
  115. package/dist/docs/skills/otel.html +4 -4
  116. package/dist/docs/skills/setup-slack.html +4 -4
  117. package/dist/docs/storage.html +4 -4
  118. package/dist/docs/templates/agentic-owners.html +4 -4
  119. package/dist/docs/templates/agents-md.html +4 -4
  120. package/dist/docs/templates/code-wiki.html +4 -4
  121. package/dist/docs/templates/demo.html +4 -4
  122. package/dist/docs/templates/grokbot-agents.html +4 -4
  123. package/dist/docs/templates/pr-autofixer.html +4 -4
  124. package/dist/docs/templates/security-help.html +4 -4
  125. package/dist/docs/templates/security-reviewer.html +4 -4
  126. package/dist/docs/templates/triage.html +4 -4
  127. package/dist/docs/troubleshooting.html +5 -5
  128. package/dist/docs/troubleshooting.md +1 -1
  129. package/dist/extensions/improve/extension.d.ts +46 -0
  130. package/dist/extensions/improve/extension.d.ts.map +1 -0
  131. package/dist/extensions/improve/extension.js +41 -0
  132. package/dist/extensions/improve/skills/yourself.d.ts +4 -0
  133. package/dist/extensions/improve/skills/yourself.d.ts.map +1 -0
  134. package/dist/extensions/improve/skills/yourself.js +43 -0
  135. package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
  136. package/dist/internal/builtin-tools/artifacts.js +2 -3
  137. package/dist/internal/channel-route-dispatch.d.ts +13 -0
  138. package/dist/internal/channel-route-dispatch.d.ts.map +1 -0
  139. package/dist/internal/channel-route-dispatch.js +62 -0
  140. package/dist/internal/channel-state.d.ts +17 -0
  141. package/dist/internal/channel-state.d.ts.map +1 -0
  142. package/dist/internal/channel-state.js +78 -0
  143. package/dist/internal/cli-ax.d.ts +7 -0
  144. package/dist/internal/cli-ax.d.ts.map +1 -1
  145. package/dist/internal/cli-ax.js +99 -1
  146. package/dist/internal/cli-cursor.d.ts.map +1 -1
  147. package/dist/internal/cli-cursor.js +2 -0
  148. package/dist/internal/cli-deploy.d.ts.map +1 -1
  149. package/dist/internal/cli-deploy.js +38 -14
  150. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  151. package/dist/internal/cli-mcp-oauth.js +15 -0
  152. package/dist/internal/cli-mcp.d.ts.map +1 -1
  153. package/dist/internal/cli-mcp.js +12 -0
  154. package/dist/internal/cli-slack.d.ts.map +1 -1
  155. package/dist/internal/cli-slack.js +8 -2
  156. package/dist/internal/cursor/credentials.d.ts +8 -2
  157. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  158. package/dist/internal/cursor/credentials.js +27 -5
  159. package/dist/internal/deploy-client.d.ts +27 -0
  160. package/dist/internal/deploy-client.d.ts.map +1 -1
  161. package/dist/internal/deploy-client.js +32 -0
  162. package/dist/internal/deploy-manifest.d.ts +23 -0
  163. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  164. package/dist/internal/deploy-manifest.js +84 -1
  165. package/dist/internal/describe-error.d.ts +1 -0
  166. package/dist/internal/describe-error.d.ts.map +1 -1
  167. package/dist/internal/describe-error.js +25 -0
  168. package/dist/internal/guest-network.d.ts +4 -10
  169. package/dist/internal/guest-network.d.ts.map +1 -1
  170. package/dist/internal/guest-network.js +42 -26
  171. package/dist/internal/hosted-admission-adapter.d.ts +2 -0
  172. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  173. package/dist/internal/hosted-catch-protocol.d.ts +51 -0
  174. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -0
  175. package/dist/internal/hosted-catch-protocol.js +103 -0
  176. package/dist/internal/hosted-catch.d.ts +40 -0
  177. package/dist/internal/hosted-catch.d.ts.map +1 -0
  178. package/dist/internal/hosted-catch.js +149 -0
  179. package/dist/internal/hosted-delivery-protocol.d.ts +41 -0
  180. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  181. package/dist/internal/hosted-delivery-protocol.js +249 -0
  182. package/dist/internal/hosted-delivery.d.ts +10 -1
  183. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  184. package/dist/internal/hosted-delivery.js +100 -22
  185. package/dist/internal/hosted-execution-diag.d.ts +4 -1
  186. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  187. package/dist/internal/hosted-execution-diag.js +13 -4
  188. package/dist/internal/hosted-execution-flush.d.ts +3 -0
  189. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  190. package/dist/internal/hosted-execution-flush.js +2 -4
  191. package/dist/internal/http-control-plane-session.d.ts +30 -0
  192. package/dist/internal/http-control-plane-session.d.ts.map +1 -0
  193. package/dist/internal/http-control-plane-session.js +83 -0
  194. package/dist/internal/legacy-command-guard.d.ts +22 -0
  195. package/dist/internal/legacy-command-guard.d.ts.map +1 -0
  196. package/dist/internal/legacy-command-guard.js +51 -0
  197. package/dist/internal/platform-timers.d.ts +7 -0
  198. package/dist/internal/platform-timers.d.ts.map +1 -1
  199. package/dist/internal/platform-timers.js +139 -0
  200. package/dist/internal/reminder-control-plane-protocol.d.ts +2 -0
  201. package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -1
  202. package/dist/internal/reminder-control-plane-protocol.js +9 -2
  203. package/dist/internal/reminder-runner.d.ts +8 -0
  204. package/dist/internal/reminder-runner.d.ts.map +1 -1
  205. package/dist/internal/reminder-runner.js +36 -9
  206. package/dist/internal/resolve-prod-target.d.ts +2 -0
  207. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  208. package/dist/internal/resolve-prod-target.js +13 -0
  209. package/dist/internal/sdk-runner.d.ts.map +1 -1
  210. package/dist/internal/sdk-runner.js +4 -3
  211. package/dist/internal/server.d.ts.map +1 -1
  212. package/dist/internal/server.js +57 -56
  213. package/dist/internal/session-engine.d.ts +2 -6
  214. package/dist/internal/session-engine.d.ts.map +1 -1
  215. package/dist/internal/session-engine.js +95 -67
  216. package/dist/playground/assets/{index-Bq2HpEQB.js → index-BMDqAeXu.js} +28 -28
  217. package/dist/playground/assets/index-LUgJoWdL.css +1 -0
  218. package/dist/playground/index.html +2 -2
  219. package/dist/storage-backends/cursor-hosted.d.ts +6 -0
  220. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  221. package/dist/storage-backends/cursor-hosted.js +29 -1
  222. package/dist/types.d.ts +33 -5
  223. package/dist/types.d.ts.map +1 -1
  224. package/docs/README.md +4 -0
  225. package/docs/deployment.md +7 -2
  226. package/docs/evals.md +3 -2
  227. package/docs/guides/cloud-agents.md +4 -3
  228. package/docs/guides/github.md +2 -1
  229. package/docs/guides/grokbot-agents.md +2 -2
  230. package/docs/guides/improve.md +96 -0
  231. package/docs/guides/slack.md +2 -1
  232. package/docs/reference/agent-config.md +5 -2
  233. package/docs/reference/cli.md +18 -11
  234. package/docs/reference/connections.md +2 -1
  235. package/docs/reference/extensions.md +2 -0
  236. package/docs/scaffolding-agents.md +2 -1
  237. package/docs/troubleshooting.md +1 -1
  238. package/package.json +8 -1
  239. package/skills/create-agent/SKILL.md +1 -1
  240. package/skills/debug/SKILL.md +1 -1
  241. package/skills/evals/SKILL.md +1 -1
  242. package/skills/framework-map/SKILL.md +4 -2
  243. package/skills/github/SKILL.md +1 -1
  244. package/src/bin/agent-serve.ts +27 -2
  245. package/src/channels/github/github-channel.ts +8 -8
  246. package/src/channels/github/types.ts +5 -0
  247. package/src/channels/origin/origin-channel.ts +29 -13
  248. package/src/channels/origin/types.ts +5 -0
  249. package/src/channels.ts +157 -10
  250. package/src/connections.ts +2 -1
  251. package/src/extensions/improve/extension.ts +70 -0
  252. package/src/extensions/improve/skills/yourself.ts +50 -0
  253. package/src/internal/builtin-tools/artifacts.ts +2 -3
  254. package/src/internal/channel-route-dispatch.ts +66 -0
  255. package/src/internal/channel-state.ts +96 -0
  256. package/src/internal/cli-ax.ts +110 -1
  257. package/src/internal/cli-cursor.ts +4 -1
  258. package/src/internal/cli-deploy.ts +50 -10
  259. package/src/internal/cli-mcp-oauth.ts +18 -0
  260. package/src/internal/cli-mcp.ts +11 -0
  261. package/src/internal/cli-slack.ts +15 -2
  262. package/src/internal/cursor/credentials.ts +35 -7
  263. package/src/internal/deploy-client.ts +54 -0
  264. package/src/internal/deploy-manifest.ts +115 -1
  265. package/src/internal/describe-error.ts +28 -0
  266. package/src/internal/guest-network.ts +43 -29
  267. package/src/internal/hosted-admission-adapter.ts +2 -0
  268. package/src/internal/hosted-catch-protocol.ts +130 -0
  269. package/src/internal/hosted-catch.ts +192 -0
  270. package/src/internal/hosted-delivery-protocol.ts +387 -0
  271. package/src/internal/hosted-delivery.ts +155 -22
  272. package/src/internal/hosted-execution-diag.ts +21 -3
  273. package/src/internal/hosted-execution-flush.ts +6 -3
  274. package/src/internal/http-control-plane-session.ts +104 -0
  275. package/src/internal/legacy-command-guard.ts +59 -0
  276. package/src/internal/platform-timers.ts +191 -0
  277. package/src/internal/reminder-control-plane-protocol.ts +15 -2
  278. package/src/internal/reminder-runner.ts +60 -9
  279. package/src/internal/resolve-prod-target.ts +15 -0
  280. package/src/internal/sdk-runner.ts +2 -1
  281. package/src/internal/server.ts +89 -79
  282. package/src/internal/session-engine.ts +141 -83
  283. package/src/storage-backends/cursor-hosted.ts +40 -1
  284. package/src/types.ts +39 -6
  285. package/dist/docs/assets/chunks/@localSearchIndexroot.DXXZxiMv.js +0 -1
  286. package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +0 -9
  287. package/dist/docs/assets/index.md.BW_6tOgR.js +0 -5
  288. package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +0 -1
  289. package/dist/docs/assets/troubleshooting.md.Cus_YZga.js +0 -1
  290. package/dist/playground/assets/index-CZKKNlmb.css +0 -1
  291. /package/dist/docs/assets/{evals.md.CbMoebP1.lean.js → evals.md.C1ekS3k2.lean.js} +0 -0
  292. /package/dist/docs/assets/{guides_github.md.c0gdGJ-D.lean.js → guides_github.md.BH33UEBJ.lean.js} +0 -0
  293. /package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.lean.js → guides_grokbot-agents.md.DyV-WArv.lean.js} +0 -0
  294. /package/dist/docs/assets/{index.md.BW_6tOgR.lean.js → index.md.BjH1w2ZW.lean.js} +0 -0
  295. /package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.lean.js → reference_agent-config.md.CvoL6pof.lean.js} +0 -0
  296. /package/dist/docs/assets/{reference_connections.md.Di6jJAXF.lean.js → reference_connections.md.BojkC6c5.lean.js} +0 -0
  297. /package/dist/docs/assets/{reference_extensions.md.CGmMLblt.lean.js → reference_extensions.md.CPWt00ds.lean.js} +0 -0
  298. /package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.lean.js → scaffolding-agents.md.Kctn3OVb.lean.js} +0 -0
  299. /package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.lean.js → skills_create-agent.md.Q3h6Je-e.lean.js} +0 -0
  300. /package/dist/docs/assets/{skills_evals.md.723kpUmA.lean.js → skills_evals.md.BhovOvrl.lean.js} +0 -0
  301. /package/dist/docs/assets/{skills_github.md.D0JahM8c.lean.js → skills_github.md.hgFX_oKY.lean.js} +0 -0
  302. /package/dist/docs/assets/{troubleshooting.md.Cus_YZga.lean.js → troubleshooting.md.CYEAO9bM.lean.js} +0 -0
@@ -114,6 +114,10 @@ import {
114
114
  sessionClock,
115
115
  } from "./as-of.js";
116
116
  import { SessionAuthError, samePrincipal } from "./auth.js";
117
+ import {
118
+ mergeChannelStateMutation,
119
+ mergeChannelStateSkipNull,
120
+ } from "./channel-state.js";
117
121
  import { mergeCloudOptions, resolveSessionRuntime } from "./cloud-merge.js";
118
122
  import {
119
123
  applyCloudUsageToEvents,
@@ -132,7 +136,7 @@ import {
132
136
  resolveV2Key,
133
137
  V2EngineError,
134
138
  } from "./continuation-identity.js";
135
- import { describeError } from "./describe-error.js";
139
+ import { describeError, describeErrorCode } from "./describe-error.js";
136
140
  import { isDevMode } from "./dev-mode.js";
137
141
  import { type EventLogMemoryStats, EventLogStore } from "./event-log.js";
138
142
  import { TurnEventMapper } from "./event-mapper.js";
@@ -160,6 +164,7 @@ import {
160
164
  HostedAdmissionLocalSendError,
161
165
  isDuringHostedAdmission,
162
166
  } from "./hosted-admission-context.js";
167
+ import { hostedSessionResumeKey } from "./hosted-catch-protocol.js";
163
168
  import {
164
169
  formatContinuationToken,
165
170
  newContinuationKey,
@@ -217,11 +222,17 @@ import {
217
222
  } from "./workspace-sync.js";
218
223
 
219
224
  export const HTTP_CHANNEL_ID = "http";
225
+ export { mergeChannelStateSkipNull } from "./channel-state.js";
220
226
  export { SCHEDULE_CHANNEL_PREFIX } from "./prompt-context.js";
221
227
 
222
228
  /** Authored surfaces mirrored onto the Agent Store before a first cloud prompt. */
223
229
  type CloudSyncSurface = "skills" | "workspace";
224
230
 
231
+ interface EventDispatchContext {
232
+ channelState: JsonValue;
233
+ session: SessionInfo;
234
+ }
235
+
225
236
  /** The Agent Store cloud turns read authored files from, and where the VM mounts it. */
226
237
  interface CloudStoreTarget {
227
238
  sink: FileSink;
@@ -1019,6 +1030,18 @@ export class SessionEngine {
1019
1030
  sendOptions.continuationToken
1020
1031
  );
1021
1032
  }
1033
+ if (
1034
+ existing === undefined &&
1035
+ sendOptions.hostedSessionId !== undefined &&
1036
+ sendOptions.mailboxContinuation?.key ===
1037
+ hostedSessionResumeKey(sendOptions.hostedSessionId)
1038
+ ) {
1039
+ // Explicit control-plane resume of an existing session: the CP named
1040
+ // the session by its own id and stamped the matching resume key. The
1041
+ // session keeps its original continuation key (a PR lane must stay
1042
+ // addressable by its webhooks); this is a follow-up turn by id.
1043
+ existing = await this.getOrRestoreSession(sendOptions.hostedSessionId);
1044
+ }
1022
1045
 
1023
1046
  if (existing !== undefined) {
1024
1047
  if (
@@ -1668,10 +1691,16 @@ export class SessionEngine {
1668
1691
  isFirstTurn,
1669
1692
  abort.signal
1670
1693
  );
1694
+ if (outcome.status === "cancelled") {
1695
+ outcome.cancellationReason = abort.signal.aborted
1696
+ ? "signal"
1697
+ : "runner";
1698
+ }
1671
1699
  } catch (error) {
1672
1700
  outcome = {
1673
1701
  status: "error",
1674
1702
  errorMessage: describeError(error),
1703
+ errorCode: describeErrorCode(error),
1675
1704
  };
1676
1705
  } finally {
1677
1706
  clearInterval(poll);
@@ -2192,6 +2221,11 @@ export class SessionEngine {
2192
2221
  const sessionId = record.sessionId;
2193
2222
  const workspaceDir = this.scaffoldDir(record);
2194
2223
  const harnessCwd = this.harnessCwd(record);
2224
+ const turnChannelState = structuredClone(record.channelState ?? null);
2225
+ const eventContext: EventDispatchContext = {
2226
+ channelState: structuredClone(turnChannelState),
2227
+ session: this.sessionInfo(record),
2228
+ };
2195
2229
  // Hold the open log so tool events append synchronously. Fire-and-forget
2196
2230
  // `appendEvent` races parallel tool completions and delays the live stream
2197
2231
  // until the next await tick — often after *all* parallel tools finish.
@@ -2199,7 +2233,7 @@ export class SessionEngine {
2199
2233
  const emit = (payload: SessionEventPayload): void => {
2200
2234
  try {
2201
2235
  const event = log.append({ ...payload, turnId });
2202
- this.queueDispatch(sessionId, event);
2236
+ this.queueDispatch(sessionId, event, eventContext);
2203
2237
  } catch (error) {
2204
2238
  this.logger(
2205
2239
  `[agent-sdk] failed to record event for ${sessionId}: ${describeError(error)}`
@@ -2311,6 +2345,7 @@ export class SessionEngine {
2311
2345
  isFirstTurn,
2312
2346
  instructionsInvisibleToHarness,
2313
2347
  emit,
2348
+ eventContext,
2314
2349
  async (update) => {
2315
2350
  const turn = this.turnRoots.get(sessionId);
2316
2351
  if (turn !== undefined) {
@@ -2352,7 +2387,11 @@ export class SessionEngine {
2352
2387
  } catch (error) {
2353
2388
  this.approvals.cancelSession(sessionId, "deny");
2354
2389
  this.auths.cancelSession(sessionId, "deny");
2355
- outcome = { status: "error", errorMessage: describeError(error) };
2390
+ outcome = {
2391
+ status: "error",
2392
+ errorMessage: describeError(error),
2393
+ errorCode: describeErrorCode(error),
2394
+ };
2356
2395
  } finally {
2357
2396
  permit.release();
2358
2397
  this.dropTurnFileSystem(sessionId);
@@ -2371,6 +2410,7 @@ export class SessionEngine {
2371
2410
  if (mapper.title !== undefined) {
2372
2411
  const title = mapper.title;
2373
2412
  await this.updateRecord(sessionId, (current) => ({ ...current, title }));
2413
+ eventContext.session = { ...eventContext.session, title };
2374
2414
  }
2375
2415
 
2376
2416
  const finalResult = outcome.result ?? mapper.finalText;
@@ -2395,7 +2435,8 @@ export class SessionEngine {
2395
2435
  text: finalResult,
2396
2436
  dryRun: record.dryRun === true,
2397
2437
  ctx: {
2398
- session: this.sessionInfo(record),
2438
+ session: eventContext.session,
2439
+ channelState: turnChannelState,
2399
2440
  host: this.hostForSession(sessionId),
2400
2441
  artifacts: this.artifactsApi({ sessionId, turnId }),
2401
2442
  stateRoot: this.stateRoot,
@@ -2414,29 +2455,38 @@ export class SessionEngine {
2414
2455
  }
2415
2456
 
2416
2457
  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,
2458
+ await this.appendEvent(
2459
+ sessionId,
2460
+ {
2461
+ type: "turn.completed",
2462
+ turnId,
2463
+ data: {
2464
+ result: finalResult,
2465
+ usage: finalUsage,
2466
+ cost: finalCost,
2467
+ },
2424
2468
  },
2425
- });
2469
+ eventContext
2470
+ );
2426
2471
  } else {
2427
2472
  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")),
2473
+ await this.appendEvent(
2474
+ sessionId,
2475
+ {
2476
+ type: "turn.failed",
2477
+ turnId,
2478
+ data: {
2479
+ status: outcome.status,
2480
+ message: interrupted
2481
+ ? "turn interrupted"
2482
+ : (outcome.errorMessage ??
2483
+ (outcome.status === "cancelled"
2484
+ ? "turn cancelled"
2485
+ : "turn failed")),
2486
+ },
2438
2487
  },
2439
- });
2488
+ eventContext
2489
+ );
2440
2490
  }
2441
2491
 
2442
2492
  const current = await this.sessions.get(sessionId);
@@ -2450,15 +2500,20 @@ export class SessionEngine {
2450
2500
  type: "session.failed",
2451
2501
  turnId,
2452
2502
  data: { message: outcome.errorMessage ?? "task failed" },
2453
- }
2503
+ },
2504
+ eventContext
2454
2505
  );
2455
2506
  await this.wipeCloudSessionWorkspace(sessionId);
2456
2507
  } else {
2457
- await this.appendEvent(sessionId, {
2458
- type: "session.waiting",
2459
- turnId,
2460
- data: {},
2461
- });
2508
+ await this.appendEvent(
2509
+ sessionId,
2510
+ {
2511
+ type: "session.waiting",
2512
+ turnId,
2513
+ data: {},
2514
+ },
2515
+ eventContext
2516
+ );
2462
2517
  }
2463
2518
 
2464
2519
  return {
@@ -2664,6 +2719,7 @@ export class SessionEngine {
2664
2719
  isFirstTurn: boolean,
2665
2720
  instructionsInvisibleToHarness: boolean,
2666
2721
  emit: (payload: SessionEventPayload) => void,
2722
+ eventContext: EventDispatchContext,
2667
2723
  onUpdate: RunnerTurnRequest["onUpdate"],
2668
2724
  signal: AbortSignal,
2669
2725
  images?: Array<{ data: string; mimeType: string }>
@@ -2944,16 +3000,21 @@ export class SessionEngine {
2944
3000
  sdkAgentId,
2945
3001
  }));
2946
3002
  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
- : {}),
3003
+ eventContext.session = { ...eventContext.session, sdkAgentId };
3004
+ await this.appendEvent(
3005
+ record.sessionId,
3006
+ {
3007
+ type: "agent.bound",
3008
+ turnId,
3009
+ data: {
3010
+ sdkAgentId,
3011
+ ...(sdkAgentId.startsWith("bc-")
3012
+ ? { url: `https://cursor.com/agents/${sdkAgentId}` }
3013
+ : {}),
3014
+ },
2955
3015
  },
2956
- });
3016
+ eventContext
3017
+ );
2957
3018
  },
2958
3019
  };
2959
3020
  }
@@ -4606,21 +4667,26 @@ export class SessionEngine {
4606
4667
 
4607
4668
  private async appendEvent(
4608
4669
  sessionId: string,
4609
- payload: SessionEventPayload & { turnId?: string }
4670
+ payload: SessionEventPayload & { turnId?: string },
4671
+ context?: EventDispatchContext
4610
4672
  ): Promise<SessionEvent> {
4611
4673
  const log = await this.logs.get(sessionId);
4612
4674
  const event = log.append(payload);
4613
- this.queueDispatch(sessionId, event);
4675
+ this.queueDispatch(sessionId, event, context);
4614
4676
  return event;
4615
4677
  }
4616
4678
 
4617
- private queueDispatch(sessionId: string, event: SessionEvent): void {
4679
+ private queueDispatch(
4680
+ sessionId: string,
4681
+ event: SessionEvent,
4682
+ context?: EventDispatchContext
4683
+ ): void {
4618
4684
  // Single funnel for both append paths (appendEvent + the held-log emit),
4619
4685
  // so the storage sink sees every durable event exactly once.
4620
4686
  this.storage?.event(event);
4621
4687
  const chain = this.dispatchChains.get(sessionId) ?? Promise.resolve();
4622
4688
  const next = chain
4623
- .then(() => this.dispatchEvent(sessionId, event))
4689
+ .then(() => this.dispatchEvent(sessionId, event, context))
4624
4690
  .catch((error) => {
4625
4691
  this.logger(
4626
4692
  `[agent-sdk] event dispatch failed for ${sessionId}: ${describeError(error)}`
@@ -4637,16 +4703,27 @@ export class SessionEngine {
4637
4703
 
4638
4704
  private async dispatchEvent(
4639
4705
  sessionId: string,
4640
- event: SessionEvent
4706
+ event: SessionEvent,
4707
+ context?: EventDispatchContext
4641
4708
  ): Promise<void> {
4642
4709
  const record = await this.sessions.get(sessionId);
4643
4710
  if (record === undefined) {
4644
4711
  return;
4645
4712
  }
4713
+ const channelState =
4714
+ context === undefined
4715
+ ? (record.channelState ?? null)
4716
+ : context.channelState;
4717
+ const channelStateBefore =
4718
+ context === undefined ? undefined : structuredClone(channelState);
4646
4719
 
4647
4720
  const sessionCtx: SessionContext = {
4648
- session: this.sessionInfo(record),
4721
+ session: context?.session ?? this.sessionInfo(record),
4649
4722
  host: this.hostForSession(record.sessionId),
4723
+ artifacts: this.artifactsApi({
4724
+ sessionId: record.sessionId,
4725
+ turnId: event.turnId,
4726
+ }),
4650
4727
  };
4651
4728
  const channelEvents = this.channelEventHandlersFor(record.channelId);
4652
4729
  if (channelEvents !== undefined) {
@@ -4658,7 +4735,7 @@ export class SessionEngine {
4658
4735
  ];
4659
4736
  const channelCtx = {
4660
4737
  channelId: record.channelId,
4661
- state: (record.channelState ?? null) as JsonValue,
4738
+ state: channelState,
4662
4739
  continuationToken: record.continuationKey,
4663
4740
  setContinuationToken: (token: string | null) =>
4664
4741
  this.setContinuationToken(sessionId, token),
@@ -4675,8 +4752,21 @@ export class SessionEngine {
4675
4752
  );
4676
4753
  }
4677
4754
  }
4678
- // Handlers mutate channel state in place; persist after each batch.
4679
- await this.updateRecord(sessionId, (current) => ({ ...current }));
4755
+ if (context === undefined || channelStateBefore === undefined) {
4756
+ // Handlers mutate live channel state in place; save the current record.
4757
+ await this.updateRecord(sessionId, (current) => ({ ...current }));
4758
+ } else {
4759
+ const updatedState = channelCtx.state as JsonValue;
4760
+ context.channelState = updatedState;
4761
+ await this.updateRecord(sessionId, (current) => ({
4762
+ ...current,
4763
+ channelState: mergeChannelStateMutation({
4764
+ current: current.channelState,
4765
+ before: channelStateBefore,
4766
+ after: updatedState,
4767
+ }),
4768
+ }));
4769
+ }
4680
4770
  }
4681
4771
 
4682
4772
  for (const hook of this.project.hooks) {
@@ -4697,10 +4787,6 @@ export class SessionEngine {
4697
4787
  continuationToken: record.continuationKey,
4698
4788
  },
4699
4789
  stateRoot: this.stateRoot,
4700
- artifacts: this.artifactsApi({
4701
- sessionId: record.sessionId,
4702
- turnId: event.turnId,
4703
- }),
4704
4790
  });
4705
4791
  } catch (error) {
4706
4792
  this.logger(
@@ -4776,6 +4862,10 @@ export class SessionEngine {
4776
4862
  await active;
4777
4863
  continue;
4778
4864
  }
4865
+ const dispatch = this.dispatchChains.get(sessionId);
4866
+ if (dispatch !== undefined) {
4867
+ await dispatch.catch(() => {});
4868
+ }
4779
4869
  return this.lastOutcomes.get(sessionId) ?? { status: "finished" };
4780
4870
  }
4781
4871
  }
@@ -5770,38 +5860,6 @@ function mergePendingWorkspaceFiles(
5770
5860
  return { ...current, ...incoming };
5771
5861
  }
5772
5862
 
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
5863
  function eventsNdjson(events: SessionEvent[]): string | undefined {
5806
5864
  if (events.length === 0) {
5807
5865
  return undefined;
@@ -169,6 +169,30 @@ export interface KvListKeysResponse {
169
169
  truncated?: boolean;
170
170
  }
171
171
 
172
+ const STORAGE_RPC_ERROR_CODES = new Set([
173
+ "agentsdk_kv_credential_missing",
174
+ "agentsdk_kv_cursor_invalid",
175
+ "agentsdk_kv_deployment_unbound",
176
+ "agentsdk_kv_key_invalid",
177
+ "agentsdk_kv_request_invalid",
178
+ "agentsdk_kv_storage_not_allowed",
179
+ "agentsdk_kv_value_invalid",
180
+ "agentsdk_kv_version_invalid",
181
+ ]);
182
+
183
+ export class StorageRpcError extends Error {
184
+ readonly code = "agent_dependency_failed";
185
+ readonly reasonCode: string;
186
+ readonly status: number;
187
+
188
+ constructor(message: string, reasonCode: string, status: number) {
189
+ super(message);
190
+ this.name = "StorageRpcError";
191
+ this.reasonCode = reasonCode;
192
+ this.status = status;
193
+ }
194
+ }
195
+
172
196
  function toCasResult(response: KvCasResponse): KvCasResult {
173
197
  if (response.ok) {
174
198
  if (response.version === null) {
@@ -251,7 +275,22 @@ export async function storageRpc<T>(
251
275
  typeof (parsed as { error: unknown }).error === "string"
252
276
  ? (parsed as { error: string }).error
253
277
  : `HTTP ${response.status}`;
254
- throw new Error(`cursorHostedStorage ${path}: ${error}`);
278
+ const candidate =
279
+ parsed !== null &&
280
+ typeof parsed === "object" &&
281
+ "code" in parsed &&
282
+ typeof (parsed as { code: unknown }).code === "string"
283
+ ? (parsed as { code: string }).code
284
+ : undefined;
285
+ const code =
286
+ candidate !== undefined && STORAGE_RPC_ERROR_CODES.has(candidate)
287
+ ? candidate
288
+ : "agentsdk_storage_http_error";
289
+ throw new StorageRpcError(
290
+ `cursorHostedStorage ${path}: ${error}`,
291
+ code,
292
+ response.status
293
+ );
255
294
  }
256
295
  return parsed as T;
257
296
  }
package/src/types.ts CHANGED
@@ -1778,7 +1778,14 @@ export type SessionEventPayload =
1778
1778
  type: "turn.bound";
1779
1779
  data: { requestId: string };
1780
1780
  }
1781
- | { type: "turn.failed"; data: { message: string } }
1781
+ | {
1782
+ type: "turn.failed";
1783
+ data: {
1784
+ message: string;
1785
+ /** Machine-readable terminal status. Omitted on legacy stored events. */
1786
+ status?: "error" | "cancelled";
1787
+ };
1788
+ }
1782
1789
  | {
1783
1790
  /**
1784
1791
  * A Slack follow-up queued mid-turn reached the running agent: the
@@ -1953,6 +1960,10 @@ export interface TurnOutcome {
1953
1960
  status: "finished" | "error" | "cancelled";
1954
1961
  result?: string;
1955
1962
  errorMessage?: string;
1963
+ /** Stable machine-readable runner code when the failure supplied one. */
1964
+ errorCode?: string;
1965
+ /** Why a cancelled turn stopped, when the engine observed the boundary. */
1966
+ cancellationReason?: "signal" | "runner";
1956
1967
  usage?: TurnUsage;
1957
1968
  /** Cost of {@link usage} from the Cloud Agents cost endpoint. */
1958
1969
  cost?: TurnCost;
@@ -2023,7 +2034,10 @@ export interface ChannelSession {
2023
2034
  getEventStream(options?: {
2024
2035
  startIndex?: number;
2025
2036
  }): Promise<ReadableStream<Uint8Array>>;
2026
- /** Resolves when the currently running turn reaches a terminal event. */
2037
+ /**
2038
+ * Resolves after the currently running turn reaches a terminal event and
2039
+ * handlers already queued for that session have settled.
2040
+ */
2027
2041
  waitForCompletion(): Promise<TurnOutcome>;
2028
2042
  /** Re-key the session's channel-local continuation token. */
2029
2043
  setContinuationToken(token: string | null): Promise<void>;
@@ -2384,7 +2398,14 @@ export interface ReceiveInput {
2384
2398
  target?: JsonObject;
2385
2399
  }
2386
2400
 
2387
- /** Per-event channel context: live (persisted) state plus session ops. */
2401
+ /**
2402
+ * Per-event channel context. `state` is mutable. Turn events receive the
2403
+ * state snapshot captured for that turn; handler mutations are recursively
2404
+ * merged into the latest persisted state so fields refreshed by overlapping
2405
+ * deliveries survive. At paths changed by the handler, objects merge
2406
+ * recursively, arrays and scalars replace the latest value, and deletion
2407
+ * removes the latest value. Events outside a turn receive current live state.
2408
+ */
2388
2409
  export interface ChannelEventContext<TState = JsonValue> {
2389
2410
  channelId: string;
2390
2411
  state: TState;
@@ -2401,6 +2422,11 @@ export interface SessionContext {
2401
2422
  * relative path cannot read another session's files.
2402
2423
  */
2403
2424
  host: HostContext;
2425
+ /**
2426
+ * Durable artifacts bound to this event's session and turn. `tag`
2427
+ * auto-fills both ids and rejects a conflicting explicit `sessionId`.
2428
+ */
2429
+ artifacts: ArtifactsApi;
2404
2430
  }
2405
2431
 
2406
2432
  export type ChannelEventHandler<
@@ -2711,6 +2737,8 @@ export type ArtifactsDefinition = ArtifactsConfig &
2711
2737
  */
2712
2738
  export interface ResultContext {
2713
2739
  session: SessionInfo;
2740
+ /** Durable channel state captured for this turn. */
2741
+ channelState: JsonValue;
2714
2742
  host: HostContext;
2715
2743
  artifacts: ArtifactsApi;
2716
2744
  stateRoot: string;
@@ -3542,8 +3570,11 @@ export interface ServeOptions {
3542
3570
  stateRoot?: string;
3543
3571
  /**
3544
3572
  * Cursor API key for the SDK runner and Cursor account MCP connections.
3545
- * When omitted, falls back to `CURSOR_API_KEY`, then to the credential
3546
- * stored by `agent-sdk login`.
3573
+ * When omitted, falls back to `CURSOR_API_KEY`, then
3574
+ * `CURSOR_API_KEY_FILE` (hosted default `/run/cursor/secrets/CURSOR_API_KEY`
3575
+ * when unset), then `CURSOR_SERVICE_ACCOUNT_KEY`, then the credential
3576
+ * stored by `agent-sdk login`. A bind file wins over
3577
+ * `CURSOR_SERVICE_ACCOUNT_KEY`.
3547
3578
  */
3548
3579
  apiKey?: string;
3549
3580
  /** Run schedules on their cron cadence. Defaults to `!dev`. */
@@ -3628,7 +3659,9 @@ export interface ServeOptions {
3628
3659
  * GitHub and Origin subscriptions are registered independently.
3629
3660
  * The stream is read as the host's Cursor user, so this requires a signed-in
3630
3661
  * host: `serve` throws when no key resolves from `apiKey` here,
3631
- * {@link ServeOptions.apiKey}, `CURSOR_API_KEY`, or `agent-sdk login`.
3662
+ * {@link ServeOptions.apiKey}, `CURSOR_API_KEY`, `CURSOR_API_KEY_FILE`
3663
+ * (hosted default `/run/cursor/secrets/CURSOR_API_KEY` when unset),
3664
+ * `CURSOR_SERVICE_ACCOUNT_KEY`, or `agent-sdk login`.
3632
3665
  */
3633
3666
  cursorEvents?: {
3634
3667
  repos: string[];