@cursor/july 0.1.100 → 0.1.102

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 (484) hide show
  1. package/README.md +27 -0
  2. package/dist/bin/agent-serve.js +3 -2
  3. package/dist/channels/deployments/deployments-channel.d.ts +41 -5
  4. package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
  5. package/dist/channels/deployments/deployments-channel.js +88 -8
  6. package/dist/channels/deployments/types.d.ts +4 -3
  7. package/dist/channels/deployments/types.d.ts.map +1 -1
  8. package/dist/channels/origin/defaults.d.ts +43 -0
  9. package/dist/channels/origin/defaults.d.ts.map +1 -0
  10. package/dist/channels/origin/defaults.js +111 -0
  11. package/dist/channels/origin/index.d.ts +2 -0
  12. package/dist/channels/origin/index.d.ts.map +1 -1
  13. package/dist/channels/origin/index.js +2 -0
  14. package/dist/channels/origin/origin-channel.d.ts +2 -1
  15. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  16. package/dist/channels/origin/origin-channel.js +24 -3
  17. package/dist/channels/origin/state.d.ts +32 -0
  18. package/dist/channels/origin/state.d.ts.map +1 -0
  19. package/dist/channels/origin/state.js +23 -0
  20. package/dist/channels/origin/types.d.ts +23 -1
  21. package/dist/channels/origin/types.d.ts.map +1 -1
  22. package/dist/channels/slack/api.d.ts +1 -1
  23. package/dist/channels/slack/api.d.ts.map +1 -1
  24. package/dist/channels/slack/api.js +5 -2
  25. package/dist/channels/slack/assistant.d.ts +1 -1
  26. package/dist/channels/slack/assistant.d.ts.map +1 -1
  27. package/dist/channels/slack/code-fences.d.ts +17 -0
  28. package/dist/channels/slack/code-fences.d.ts.map +1 -0
  29. package/dist/channels/slack/code-fences.js +168 -0
  30. package/dist/channels/slack/dispatch.d.ts +3 -2
  31. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  32. package/dist/channels/slack/dispatch.js +28 -8
  33. package/dist/channels/slack/inbound.d.ts +8 -0
  34. package/dist/channels/slack/inbound.d.ts.map +1 -1
  35. package/dist/channels/slack/inbound.js +28 -0
  36. package/dist/channels/slack/index.d.ts +1 -0
  37. package/dist/channels/slack/index.d.ts.map +1 -1
  38. package/dist/channels/slack/index.js +1 -0
  39. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  40. package/dist/channels/slack/live-delivery.js +11 -4
  41. package/dist/channels/slack/manifest.d.ts.map +1 -1
  42. package/dist/channels/slack/manifest.js +2 -1
  43. package/dist/connections.d.ts +18 -2
  44. package/dist/connections.d.ts.map +1 -1
  45. package/dist/connections.js +18 -2
  46. package/dist/docs/404.html +2 -2
  47. package/dist/docs/ab.html +4 -4
  48. package/dist/docs/assets/{app.DZ1e0Ycq.js → app.CLA03RCz.js} +1 -1
  49. package/dist/docs/assets/chunks/@localSearchIndexroot.FAqdWIXo.js +1 -0
  50. package/dist/docs/assets/chunks/{VPLocalSearchBox.l8omwc6D.js → VPLocalSearchBox.ifxv-cJV.js} +1 -1
  51. package/dist/docs/assets/chunks/{theme.JVcD6gel.js → theme.DWCwM6p-.js} +2 -2
  52. package/dist/docs/assets/concepts.md.rPzW2HZN.js +1 -0
  53. package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.js +9 -0
  54. package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.lean.js +1 -0
  55. package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.js → guides_cloud-runtime.md.BRirbRAN.js} +1 -1
  56. package/dist/docs/assets/index.md.Kiht7ell.js +5 -0
  57. package/dist/docs/assets/{index.md.Bb4k8kUm.lean.js → index.md.Kiht7ell.lean.js} +1 -1
  58. package/dist/docs/assets/{reference_connections.md.BiGoBAk2.js → reference_connections.md.Di6jJAXF.js} +12 -2
  59. package/dist/docs/assets/{reference_connections.md.BiGoBAk2.lean.js → reference_connections.md.Di6jJAXF.lean.js} +1 -1
  60. package/dist/docs/assets/reference_extensions.md.9WQMZe1l.js +56 -0
  61. package/dist/docs/assets/reference_extensions.md.9WQMZe1l.lean.js +1 -0
  62. package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.js → reference_http-api.md.oySXBO8o.js} +1 -1
  63. package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.js → reference_project-layout.md.CA6QP6Lw.js} +2 -2
  64. package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.lean.js → reference_project-layout.md.CA6QP6Lw.lean.js} +1 -1
  65. package/dist/docs/assets/{reference_skills.md.BFW9retM.js → reference_skills.md.l2ezAcaN.js} +1 -1
  66. package/dist/docs/assets/{reference_tools.md.CvAHsdSp.js → reference_tools.md.B1up2r9W.js} +1 -1
  67. package/dist/docs/assets/skills_framework-map.md.DDa4MeEW.js +1 -0
  68. package/dist/docs/assets/{skills_framework-map.md.BTi817yv.lean.js → skills_framework-map.md.DDa4MeEW.lean.js} +1 -1
  69. package/dist/docs/building-with-agents.html +4 -4
  70. package/dist/docs/concepts.html +5 -5
  71. package/dist/docs/concepts.md +3 -3
  72. package/dist/docs/deployment.html +4 -4
  73. package/dist/docs/evals.html +4 -4
  74. package/dist/docs/guides/agent-to-agent.html +4 -4
  75. package/dist/docs/guides/cloud-agents.html +35 -0
  76. package/dist/docs/guides/cloud-agents.md +93 -0
  77. package/dist/docs/guides/cloud-runtime.html +6 -6
  78. package/dist/docs/guides/cloud-runtime.md +2 -0
  79. package/dist/docs/guides/convert-automation.html +4 -4
  80. package/dist/docs/guides/github.html +4 -4
  81. package/dist/docs/guides/human-in-the-loop.html +4 -4
  82. package/dist/docs/guides/mcp-oauth.html +4 -4
  83. package/dist/docs/guides/opentelemetry.html +5 -5
  84. package/dist/docs/guides/slack.html +4 -4
  85. package/dist/docs/guides/webhooks.html +4 -4
  86. package/dist/docs/hashmap.json +1 -1
  87. package/dist/docs/hillclimbing.html +4 -4
  88. package/dist/docs/index.html +6 -6
  89. package/dist/docs/index.md +5 -1
  90. package/dist/docs/llms-full.txt +353 -5
  91. package/dist/docs/llms.txt +2 -0
  92. package/dist/docs/quickstart.html +4 -4
  93. package/dist/docs/reference/agent-config.html +4 -4
  94. package/dist/docs/reference/artifacts.html +4 -4
  95. package/dist/docs/reference/channels.html +5 -5
  96. package/dist/docs/reference/cli.html +4 -4
  97. package/dist/docs/reference/connections.html +16 -6
  98. package/dist/docs/reference/connections.md +31 -0
  99. package/dist/docs/reference/extensions.html +82 -0
  100. package/dist/docs/reference/extensions.md +200 -0
  101. package/dist/docs/reference/hooks.html +4 -4
  102. package/dist/docs/reference/http-api.html +6 -6
  103. package/dist/docs/reference/http-api.md +1 -1
  104. package/dist/docs/reference/instructions.html +4 -4
  105. package/dist/docs/reference/playground.html +4 -4
  106. package/dist/docs/reference/project-layout.html +6 -6
  107. package/dist/docs/reference/project-layout.md +3 -0
  108. package/dist/docs/reference/prompt.html +4 -4
  109. package/dist/docs/reference/schedules.html +4 -4
  110. package/dist/docs/reference/sessions.html +4 -4
  111. package/dist/docs/reference/skills.html +6 -6
  112. package/dist/docs/reference/skills.md +2 -0
  113. package/dist/docs/reference/subagents.html +5 -5
  114. package/dist/docs/reference/tools.html +6 -6
  115. package/dist/docs/reference/tools.md +2 -0
  116. package/dist/docs/scaffolding-agents.html +4 -4
  117. package/dist/docs/skills/ab.html +4 -4
  118. package/dist/docs/skills/create-agent.html +4 -4
  119. package/dist/docs/skills/debug.html +4 -4
  120. package/dist/docs/skills/evals.html +4 -4
  121. package/dist/docs/skills/framework-map.html +5 -5
  122. package/dist/docs/skills/framework-map.md +1 -0
  123. package/dist/docs/skills/github.html +4 -4
  124. package/dist/docs/skills/hillclimb.html +4 -4
  125. package/dist/docs/skills/index.html +4 -4
  126. package/dist/docs/skills/mcp-auth.html +4 -4
  127. package/dist/docs/skills/otel.html +4 -4
  128. package/dist/docs/skills/setup-slack.html +4 -4
  129. package/dist/docs/storage.html +4 -4
  130. package/dist/docs/templates/agentic-owners.html +4 -4
  131. package/dist/docs/templates/agents-md.html +4 -4
  132. package/dist/docs/templates/code-wiki.html +4 -4
  133. package/dist/docs/templates/demo.html +4 -4
  134. package/dist/docs/templates/pr-autofixer.html +4 -4
  135. package/dist/docs/templates/security-help.html +4 -4
  136. package/dist/docs/templates/security-reviewer.html +4 -4
  137. package/dist/docs/templates/triage.html +4 -4
  138. package/dist/docs/troubleshooting.html +4 -4
  139. package/dist/extensions/cursor-cloud-agents/extension.d.ts +57 -0
  140. package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -0
  141. package/dist/extensions/cursor-cloud-agents/extension.js +66 -0
  142. package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +78 -0
  143. package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -0
  144. package/dist/extensions/cursor-cloud-agents/lib/backend.js +286 -0
  145. package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts +25 -0
  146. package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts.map +1 -0
  147. package/dist/extensions/cursor-cloud-agents/lib/fleet.js +85 -0
  148. package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts +5 -0
  149. package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts.map +1 -0
  150. package/dist/extensions/cursor-cloud-agents/lib/inputs.js +4 -0
  151. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +15 -0
  152. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -0
  153. package/dist/extensions/cursor-cloud-agents/lib/repos.js +55 -0
  154. package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts +8 -0
  155. package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts.map +1 -0
  156. package/dist/extensions/cursor-cloud-agents/lib/transcript.js +15 -0
  157. package/dist/extensions/cursor-cloud-agents/skills/handoff.md +41 -0
  158. package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts +4 -0
  159. package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts.map +1 -0
  160. package/dist/extensions/cursor-cloud-agents/tools/cancel.js +26 -0
  161. package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts +4 -0
  162. package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts.map +1 -0
  163. package/dist/extensions/cursor-cloud-agents/tools/dump.js +54 -0
  164. package/dist/extensions/cursor-cloud-agents/tools/get.d.ts +4 -0
  165. package/dist/extensions/cursor-cloud-agents/tools/get.d.ts.map +1 -0
  166. package/dist/extensions/cursor-cloud-agents/tools/get.js +25 -0
  167. package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts +4 -0
  168. package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -0
  169. package/dist/extensions/cursor-cloud-agents/tools/launch.js +59 -0
  170. package/dist/extensions/cursor-cloud-agents/tools/list.d.ts +4 -0
  171. package/dist/extensions/cursor-cloud-agents/tools/list.d.ts.map +1 -0
  172. package/dist/extensions/cursor-cloud-agents/tools/list.js +36 -0
  173. package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts +4 -0
  174. package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts.map +1 -0
  175. package/dist/extensions/cursor-cloud-agents/tools/reply.js +35 -0
  176. package/dist/extensions.d.ts +73 -0
  177. package/dist/extensions.d.ts.map +1 -0
  178. package/dist/extensions.js +112 -0
  179. package/dist/files-backends/cursor-hosted.d.ts +0 -8
  180. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  181. package/dist/files-backends/cursor-hosted.js +1 -11
  182. package/dist/files.d.ts +5 -1
  183. package/dist/files.d.ts.map +1 -1
  184. package/dist/files.js +22 -18
  185. package/dist/index.d.ts +4 -3
  186. package/dist/index.d.ts.map +1 -1
  187. package/dist/index.js +3 -2
  188. package/dist/internal/advertise-tools.d.ts +4 -1
  189. package/dist/internal/advertise-tools.d.ts.map +1 -1
  190. package/dist/internal/advertise-tools.js +20 -1
  191. package/dist/internal/as-of.d.ts +18 -0
  192. package/dist/internal/as-of.d.ts.map +1 -1
  193. package/dist/internal/as-of.js +131 -0
  194. package/dist/internal/cli-deploy.d.ts.map +1 -1
  195. package/dist/internal/cli-deploy.js +64 -19
  196. package/dist/internal/continuation-identity.d.ts.map +1 -1
  197. package/dist/internal/continuation-identity.js +3 -1
  198. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  199. package/dist/internal/conversation-mirror.js +13 -15
  200. package/dist/internal/cursor/backend-client.d.ts +8 -1
  201. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  202. package/dist/internal/cursor/backend-client.js +25 -9
  203. package/dist/internal/cursor/hosted-deployment-secrets.d.ts +16 -0
  204. package/dist/internal/cursor/hosted-deployment-secrets.d.ts.map +1 -0
  205. package/dist/internal/cursor/hosted-deployment-secrets.js +61 -0
  206. package/dist/internal/cursor/hosted-store-secrets.d.ts +11 -0
  207. package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -1
  208. package/dist/internal/cursor/hosted-store-secrets.js +15 -0
  209. package/dist/internal/cursor-deployment-relay.d.ts +15 -1
  210. package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
  211. package/dist/internal/cursor-deployment-relay.js +46 -7
  212. package/dist/internal/deploy-client.d.ts +23 -0
  213. package/dist/internal/deploy-client.d.ts.map +1 -1
  214. package/dist/internal/deploy-client.js +54 -12
  215. package/dist/internal/discovery/ab.d.ts +9 -0
  216. package/dist/internal/discovery/ab.d.ts.map +1 -0
  217. package/dist/internal/discovery/ab.js +101 -0
  218. package/dist/internal/discovery/agent-config.d.ts +35 -0
  219. package/dist/internal/discovery/agent-config.d.ts.map +1 -0
  220. package/dist/internal/discovery/agent-config.js +173 -0
  221. package/dist/internal/discovery/agent.d.ts +11 -0
  222. package/dist/internal/discovery/agent.d.ts.map +1 -0
  223. package/dist/internal/discovery/agent.js +306 -0
  224. package/dist/internal/discovery/channels.d.ts +10 -0
  225. package/dist/internal/discovery/channels.d.ts.map +1 -0
  226. package/dist/internal/discovery/channels.js +97 -0
  227. package/dist/internal/discovery/connections.d.ts +17 -0
  228. package/dist/internal/discovery/connections.d.ts.map +1 -0
  229. package/dist/internal/discovery/connections.js +436 -0
  230. package/dist/internal/discovery/context.d.ts +20 -0
  231. package/dist/internal/discovery/context.d.ts.map +1 -0
  232. package/dist/internal/discovery/context.js +30 -0
  233. package/dist/internal/discovery/cursor-plugin.d.ts +25 -0
  234. package/dist/internal/discovery/cursor-plugin.d.ts.map +1 -0
  235. package/dist/internal/discovery/cursor-plugin.js +570 -0
  236. package/dist/internal/discovery/extensions.d.ts +19 -0
  237. package/dist/internal/discovery/extensions.d.ts.map +1 -0
  238. package/dist/internal/discovery/extensions.js +238 -0
  239. package/dist/internal/discovery/fs.d.ts +15 -0
  240. package/dist/internal/discovery/fs.d.ts.map +1 -0
  241. package/dist/internal/discovery/fs.js +115 -0
  242. package/dist/internal/discovery/hooks.d.ts +7 -0
  243. package/dist/internal/discovery/hooks.d.ts.map +1 -0
  244. package/dist/internal/discovery/hooks.js +48 -0
  245. package/dist/internal/discovery/info.d.ts +6 -0
  246. package/dist/internal/discovery/info.d.ts.map +1 -0
  247. package/dist/internal/discovery/info.js +141 -0
  248. package/dist/internal/discovery/instructions.d.ts +7 -0
  249. package/dist/internal/discovery/instructions.d.ts.map +1 -0
  250. package/dist/internal/discovery/instructions.js +95 -0
  251. package/dist/internal/discovery/modules.d.ts +20 -0
  252. package/dist/internal/discovery/modules.d.ts.map +1 -0
  253. package/dist/internal/discovery/modules.js +101 -0
  254. package/dist/internal/discovery/names.d.ts +12 -0
  255. package/dist/internal/discovery/names.d.ts.map +1 -0
  256. package/dist/internal/discovery/names.js +36 -0
  257. package/dist/internal/discovery/project.d.ts +53 -0
  258. package/dist/internal/discovery/project.d.ts.map +1 -0
  259. package/dist/internal/discovery/project.js +239 -0
  260. package/dist/internal/discovery/runtime.d.ts +34 -0
  261. package/dist/internal/discovery/runtime.d.ts.map +1 -0
  262. package/dist/internal/discovery/runtime.js +98 -0
  263. package/dist/internal/discovery/schedules.d.ts +7 -0
  264. package/dist/internal/discovery/schedules.d.ts.map +1 -0
  265. package/dist/internal/discovery/schedules.js +97 -0
  266. package/dist/internal/discovery/seed-files.d.ts +7 -0
  267. package/dist/internal/discovery/seed-files.d.ts.map +1 -0
  268. package/dist/internal/discovery/seed-files.js +41 -0
  269. package/dist/internal/discovery/services.d.ts +17 -0
  270. package/dist/internal/discovery/services.d.ts.map +1 -0
  271. package/dist/internal/discovery/services.js +104 -0
  272. package/dist/internal/discovery/skills.d.ts +16 -0
  273. package/dist/internal/discovery/skills.d.ts.map +1 -0
  274. package/dist/internal/discovery/skills.js +151 -0
  275. package/dist/internal/discovery/subagent.d.ts +13 -0
  276. package/dist/internal/discovery/subagent.d.ts.map +1 -0
  277. package/dist/internal/discovery/subagent.js +19 -0
  278. package/dist/internal/discovery/tools.d.ts +18 -0
  279. package/dist/internal/discovery/tools.d.ts.map +1 -0
  280. package/dist/internal/discovery/tools.js +159 -0
  281. package/dist/internal/discovery.d.ts +8 -62
  282. package/dist/internal/discovery.d.ts.map +1 -1
  283. package/dist/internal/discovery.js +8 -2210
  284. package/dist/internal/distribution.d.ts.map +1 -1
  285. package/dist/internal/distribution.js +5 -0
  286. package/dist/internal/framework-file-storage.d.ts +3 -3
  287. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  288. package/dist/internal/framework-file-storage.js +38 -9
  289. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  290. package/dist/internal/framework-storage-selection.js +8 -7
  291. package/dist/internal/frontmatter.d.ts +11 -3
  292. package/dist/internal/frontmatter.d.ts.map +1 -1
  293. package/dist/internal/frontmatter.js +29 -3
  294. package/dist/internal/hosted-delivery.d.ts +3 -1
  295. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  296. package/dist/internal/hosted-delivery.js +19 -32
  297. package/dist/internal/hosted-execution-diag.d.ts +5 -0
  298. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  299. package/dist/internal/hosted-execution-diag.js +5 -0
  300. package/dist/internal/hosted-execution-flush.d.ts +46 -0
  301. package/dist/internal/hosted-execution-flush.d.ts.map +1 -0
  302. package/dist/internal/hosted-execution-flush.js +81 -0
  303. package/dist/internal/mcp-endpoint.js +1 -0
  304. package/dist/internal/mcp-host.d.ts +2 -1
  305. package/dist/internal/mcp-host.d.ts.map +1 -1
  306. package/dist/internal/mcp-host.js +66 -29
  307. package/dist/internal/otel/collector.d.ts +13 -0
  308. package/dist/internal/otel/collector.d.ts.map +1 -1
  309. package/dist/internal/otel/collector.js +84 -17
  310. package/dist/internal/otel/http.d.ts.map +1 -1
  311. package/dist/internal/otel/http.js +2 -10
  312. package/dist/internal/otel/mcp.d.ts +16 -0
  313. package/dist/internal/otel/mcp.d.ts.map +1 -0
  314. package/dist/internal/otel/mcp.js +68 -0
  315. package/dist/internal/otel/propagation.d.ts +6 -0
  316. package/dist/internal/otel/propagation.d.ts.map +1 -0
  317. package/dist/internal/otel/propagation.js +14 -0
  318. package/dist/internal/otel/runtime.d.ts.map +1 -1
  319. package/dist/internal/otel/runtime.js +2 -0
  320. package/dist/internal/review-comments.d.ts +1 -1
  321. package/dist/internal/review-comments.d.ts.map +1 -1
  322. package/dist/internal/review-comments.js +4 -4
  323. package/dist/internal/server.d.ts +3 -0
  324. package/dist/internal/server.d.ts.map +1 -1
  325. package/dist/internal/server.js +79 -104
  326. package/dist/internal/session-engine.d.ts +14 -7
  327. package/dist/internal/session-engine.d.ts.map +1 -1
  328. package/dist/internal/session-engine.js +113 -66
  329. package/dist/internal/session-run-log.d.ts +3 -1
  330. package/dist/internal/session-run-log.d.ts.map +1 -1
  331. package/dist/internal/session-run-log.js +14 -14
  332. package/dist/internal/start-log-store.d.ts +60 -0
  333. package/dist/internal/start-log-store.d.ts.map +1 -0
  334. package/dist/internal/start-log-store.js +149 -0
  335. package/dist/internal/storage-coordinator.d.ts +4 -1
  336. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  337. package/dist/internal/storage-coordinator.js +15 -13
  338. package/dist/internal/tool-catalog.d.ts.map +1 -1
  339. package/dist/internal/tool-catalog.js +9 -6
  340. package/dist/internal/tool-policy.d.ts +8 -0
  341. package/dist/internal/tool-policy.d.ts.map +1 -1
  342. package/dist/internal/tool-policy.js +19 -7
  343. package/dist/internal/turn-cost.d.ts +14 -0
  344. package/dist/internal/turn-cost.d.ts.map +1 -1
  345. package/dist/internal/turn-cost.js +41 -9
  346. package/dist/internal/v2-hosting.d.ts +22 -0
  347. package/dist/internal/v2-hosting.d.ts.map +1 -0
  348. package/dist/internal/v2-hosting.js +23 -0
  349. package/dist/otel.d.ts +16 -0
  350. package/dist/otel.d.ts.map +1 -1
  351. package/dist/otel.js +26 -0
  352. package/dist/playground/assets/index-B6C9S9nG.css +1 -0
  353. package/dist/playground/assets/{index-DVs98vPL.js → index-ZqNoT8Ie.js} +45 -45
  354. package/dist/playground/index.html +2 -2
  355. package/dist/storage-protocol.d.ts +47 -22
  356. package/dist/storage-protocol.d.ts.map +1 -1
  357. package/dist/storage-protocol.js +90 -54
  358. package/dist/storage.d.ts +2 -2
  359. package/dist/storage.d.ts.map +1 -1
  360. package/dist/storage.js +1 -1
  361. package/dist/tools.d.ts +9 -0
  362. package/dist/tools.d.ts.map +1 -1
  363. package/dist/tools.js +9 -0
  364. package/dist/types.d.ts +154 -6
  365. package/dist/types.d.ts.map +1 -1
  366. package/dist/types.js +29 -1
  367. package/docs/README.md +5 -1
  368. package/docs/concepts.md +3 -3
  369. package/docs/guides/cloud-agents.md +98 -0
  370. package/docs/guides/cloud-runtime.md +2 -0
  371. package/docs/reference/connections.md +31 -0
  372. package/docs/reference/extensions.md +205 -0
  373. package/docs/reference/http-api.md +1 -1
  374. package/docs/reference/project-layout.md +3 -0
  375. package/docs/reference/skills.md +2 -0
  376. package/docs/reference/tools.md +2 -0
  377. package/package.json +18 -4
  378. package/skills/framework-map/SKILL.md +1 -0
  379. package/src/bin/agent-serve.ts +11 -2
  380. package/src/channels/deployments/deployments-channel.ts +117 -8
  381. package/src/channels/deployments/types.ts +4 -3
  382. package/src/channels/origin/defaults.ts +143 -0
  383. package/src/channels/origin/index.ts +2 -0
  384. package/src/channels/origin/origin-channel.ts +37 -1
  385. package/src/channels/origin/state.ts +54 -0
  386. package/src/channels/origin/types.ts +24 -0
  387. package/src/channels/slack/api.ts +6 -3
  388. package/src/channels/slack/assistant.ts +1 -1
  389. package/src/channels/slack/code-fences.ts +183 -0
  390. package/src/channels/slack/dispatch.ts +27 -2
  391. package/src/channels/slack/inbound.ts +37 -0
  392. package/src/channels/slack/index.ts +1 -0
  393. package/src/channels/slack/live-delivery.ts +16 -13
  394. package/src/channels/slack/manifest.ts +2 -1
  395. package/src/connections.ts +18 -1
  396. package/src/extensions/cursor-cloud-agents/extension.ts +120 -0
  397. package/src/extensions/cursor-cloud-agents/lib/backend.ts +395 -0
  398. package/src/extensions/cursor-cloud-agents/lib/fleet.ts +109 -0
  399. package/src/extensions/cursor-cloud-agents/lib/inputs.ts +5 -0
  400. package/src/extensions/cursor-cloud-agents/lib/repos.ts +81 -0
  401. package/src/extensions/cursor-cloud-agents/lib/transcript.ts +23 -0
  402. package/src/extensions/cursor-cloud-agents/skills/handoff.md +41 -0
  403. package/src/extensions/cursor-cloud-agents/tools/cancel.ts +19 -0
  404. package/src/extensions/cursor-cloud-agents/tools/dump.ts +51 -0
  405. package/src/extensions/cursor-cloud-agents/tools/get.ts +18 -0
  406. package/src/extensions/cursor-cloud-agents/tools/launch.ts +64 -0
  407. package/src/extensions/cursor-cloud-agents/tools/list.ts +31 -0
  408. package/src/extensions/cursor-cloud-agents/tools/reply.ts +34 -0
  409. package/src/extensions.ts +141 -0
  410. package/src/files-backends/cursor-hosted.ts +1 -17
  411. package/src/files.ts +43 -34
  412. package/src/index.ts +11 -0
  413. package/src/internal/advertise-tools.ts +37 -12
  414. package/src/internal/as-of.ts +163 -0
  415. package/src/internal/cli-deploy.ts +86 -23
  416. package/src/internal/continuation-identity.ts +3 -1
  417. package/src/internal/conversation-mirror.ts +23 -18
  418. package/src/internal/cursor/backend-client.ts +32 -10
  419. package/src/internal/cursor/hosted-deployment-secrets.ts +72 -0
  420. package/src/internal/cursor/hosted-store-secrets.ts +27 -0
  421. package/src/internal/cursor-deployment-relay.ts +65 -8
  422. package/src/internal/deploy-client.ts +73 -18
  423. package/src/internal/discovery/ab.ts +111 -0
  424. package/src/internal/discovery/agent-config.ts +222 -0
  425. package/src/internal/discovery/agent.ts +360 -0
  426. package/src/internal/discovery/channels.ts +103 -0
  427. package/src/internal/discovery/connections.ts +540 -0
  428. package/src/internal/discovery/context.ts +46 -0
  429. package/src/internal/discovery/cursor-plugin.ts +708 -0
  430. package/src/internal/discovery/extensions.ts +348 -0
  431. package/src/internal/discovery/fs.ts +108 -0
  432. package/src/internal/discovery/hooks.ts +45 -0
  433. package/src/internal/discovery/info.ts +179 -0
  434. package/src/internal/discovery/instructions.ts +113 -0
  435. package/src/internal/discovery/modules.ts +107 -0
  436. package/src/internal/discovery/names.ts +44 -0
  437. package/src/internal/discovery/project.ts +270 -0
  438. package/src/internal/discovery/runtime.ts +159 -0
  439. package/src/internal/discovery/schedules.ts +94 -0
  440. package/src/internal/discovery/seed-files.ts +37 -0
  441. package/src/internal/discovery/services.ts +124 -0
  442. package/src/internal/discovery/skills.ts +176 -0
  443. package/src/internal/discovery/subagent.ts +29 -0
  444. package/src/internal/discovery/tools.ts +182 -0
  445. package/src/internal/discovery.ts +20 -2724
  446. package/src/internal/distribution.ts +5 -0
  447. package/src/internal/framework-file-storage.ts +43 -9
  448. package/src/internal/framework-storage-selection.ts +9 -9
  449. package/src/internal/frontmatter.ts +36 -3
  450. package/src/internal/hosted-delivery.ts +38 -63
  451. package/src/internal/hosted-execution-diag.ts +6 -0
  452. package/src/internal/hosted-execution-flush.ts +142 -0
  453. package/src/internal/mcp-endpoint.ts +1 -0
  454. package/src/internal/mcp-host.ts +116 -37
  455. package/src/internal/otel/collector.ts +125 -25
  456. package/src/internal/otel/http.ts +2 -12
  457. package/src/internal/otel/mcp.ts +69 -0
  458. package/src/internal/otel/propagation.ts +17 -0
  459. package/src/internal/otel/runtime.ts +2 -0
  460. package/src/internal/review-comments.ts +5 -2
  461. package/src/internal/server.ts +81 -100
  462. package/src/internal/session-engine.ts +152 -39
  463. package/src/internal/session-run-log.ts +18 -16
  464. package/src/internal/start-log-store.ts +174 -0
  465. package/src/internal/storage-coordinator.ts +19 -16
  466. package/src/internal/tool-catalog.ts +9 -6
  467. package/src/internal/tool-policy.ts +39 -9
  468. package/src/internal/turn-cost.ts +47 -4
  469. package/src/internal/v2-hosting.ts +38 -0
  470. package/src/otel.ts +38 -0
  471. package/src/storage-protocol.ts +126 -79
  472. package/src/storage.ts +5 -0
  473. package/src/tools.ts +18 -0
  474. package/src/types.ts +213 -14
  475. package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +0 -1
  476. package/dist/docs/assets/concepts.md.lwAgBIMI.js +0 -1
  477. package/dist/docs/assets/index.md.Bb4k8kUm.js +0 -5
  478. package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +0 -1
  479. package/dist/playground/assets/index-BszoQDc6.css +0 -1
  480. /package/dist/docs/assets/{concepts.md.lwAgBIMI.lean.js → concepts.md.rPzW2HZN.lean.js} +0 -0
  481. /package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.lean.js → guides_cloud-runtime.md.BRirbRAN.lean.js} +0 -0
  482. /package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.lean.js → reference_http-api.md.oySXBO8o.lean.js} +0 -0
  483. /package/dist/docs/assets/{reference_skills.md.BFW9retM.lean.js → reference_skills.md.l2ezAcaN.lean.js} +0 -0
  484. /package/dist/docs/assets/{reference_tools.md.CvAHsdSp.lean.js → reference_tools.md.B1up2r9W.lean.js} +0 -0
@@ -138,6 +138,43 @@ export function parseAppMentionEvent(
138
138
  return delegation === undefined ? message : { ...message, delegation };
139
139
  }
140
140
 
141
+ export interface SlackAppHomeOpened {
142
+ channelId: string;
143
+ tab: string;
144
+ userId?: string;
145
+ teamId?: string;
146
+ }
147
+
148
+ /** Slack fires this when a user opens the app Home or Messages tab. */
149
+ export function parseAppHomeOpened(body: unknown): SlackAppHomeOpened | null {
150
+ const root = asRecord(body);
151
+ if (root === null || root.type !== "event_callback") {
152
+ return null;
153
+ }
154
+ const event = asRecord(root.event);
155
+ if (event === null || event.type !== "app_home_opened") {
156
+ return null;
157
+ }
158
+ const channelId = asString(event.channel);
159
+ const tab = asString(event.tab);
160
+ if (
161
+ channelId === undefined ||
162
+ channelId === "" ||
163
+ tab === undefined ||
164
+ tab === ""
165
+ ) {
166
+ return null;
167
+ }
168
+ const userId = asString(event.user);
169
+ const teamId = asString(root.team_id) ?? asString(event.team_id);
170
+ return {
171
+ channelId,
172
+ tab,
173
+ userId: userId === undefined || userId === "" ? undefined : userId,
174
+ teamId: teamId === undefined || teamId === "" ? undefined : teamId,
175
+ };
176
+ }
177
+
141
178
  export interface SlackAssistantThreadStarted {
142
179
  channelId: string;
143
180
  threadTs: string;
@@ -21,6 +21,7 @@ export * from "./auth.js";
21
21
  export * from "./blocks.js";
22
22
  export * from "./bot-mentions.js";
23
23
  export * from "./channel-watch.js";
24
+ export * from "./code-fences.js";
24
25
  export * from "./constants.js";
25
26
  export * from "./credentials.js";
26
27
  export * from "./defaults.js";
@@ -22,6 +22,7 @@ import {
22
22
  startChatStream,
23
23
  stopChatStream,
24
24
  } from "./api.js";
25
+ import { highlightCodeFences } from "./code-fences.js";
25
26
  import { SLACK_MARKDOWN_TEXT_MAX_LEN } from "./constants.js";
26
27
  import type { SlackLog } from "./log.js";
27
28
  import {
@@ -117,7 +118,7 @@ export function createStreamDeliveryStrategy(
117
118
  const openingText = markdown_text ?? "";
118
119
  const opening: StreamChunk[] = [];
119
120
  if (openingText !== "") {
120
- opening.push(markdownChunk(openingText));
121
+ opening.push(markdownChunk(highlightCodeFences(openingText)));
121
122
  }
122
123
  opening.push(...(chunks ?? []));
123
124
  if (opening.length === 0) {
@@ -181,16 +182,24 @@ export function createStreamDeliveryStrategy(
181
182
  return opened ? activeStreamTs(args.channel) : null;
182
183
  };
183
184
 
185
+ /**
186
+ * What to append for the new cumulative text, as Slack should see it: the
187
+ * block text on both sides goes through the same fence rewrite, so the
188
+ * delta lines up with what the stream already holds.
189
+ */
190
+ const streamDelta = (channel: SlackChannel, text: string): string =>
191
+ computeStreamAppend(
192
+ highlightCodeFences(channel.state.streamBlockText ?? ""),
193
+ highlightCodeFences(text)
194
+ );
195
+
184
196
  const stopWithSuffix = async (args: {
185
197
  channel: SlackChannel;
186
198
  channelId: string;
187
199
  ts: string;
188
200
  text: string;
189
201
  }): Promise<{ ok: boolean; error?: string }> => {
190
- const appendText = computeStreamAppend(
191
- args.channel.state.streamBlockText,
192
- args.text
193
- );
202
+ const appendText = streamDelta(args.channel, args.text);
194
203
  const stopped = await stopChatStream({
195
204
  botToken,
196
205
  channel: args.channelId,
@@ -299,10 +308,7 @@ export function createStreamDeliveryStrategy(
299
308
  if (ts === null) {
300
309
  return;
301
310
  }
302
- const appendText = computeStreamAppend(
303
- channel.state.streamBlockText,
304
- text
305
- );
311
+ const appendText = streamDelta(channel, text);
306
312
  if (appendText === "") {
307
313
  return;
308
314
  }
@@ -374,10 +380,7 @@ export function createStreamDeliveryStrategy(
374
380
  return { delivered: false };
375
381
  }
376
382
  // Measured before the stop attempt mutates stream state.
377
- const remainder = computeStreamAppend(
378
- channel.state.streamBlockText,
379
- text
380
- );
383
+ const remainder = streamDelta(channel, text);
381
384
  const stopped =
382
385
  channel.state.streamFull === true
383
386
  ? { ok: false, error: "msg_too_long" }
@@ -84,7 +84,8 @@ const BOT_SCOPES = [
84
84
  const BOT_EVENTS = [
85
85
  "app_mention",
86
86
  "message.im",
87
- "assistant_thread_started",
87
+ // agent_view DMs: Slack no longer fires assistant_thread_started.
88
+ "app_home_opened",
88
89
  ] as const;
89
90
 
90
91
  /** Slack's display_information.description bound. */
@@ -8,7 +8,9 @@
8
8
  * are available to the agent (SDK `mcpServers`), host (`ctx.host.mcp`),
9
9
  * and channel/schedule handlers. Pass `advertiseTools: true` for named
10
10
  * tools on local turns. Pass `effects: "read"` with `advertiseTools` to
11
- * advertise only tools the server classifies as reads. Files under
11
+ * advertise only tools the server classifies as reads. Pass `tools` as
12
+ * a name list to keep a subset, same shape as `defineAgent({ tools })`.
13
+ * Pass `disallowedTools` to drop names. Files under
12
14
  * `host-connections/` stay off the model.
13
15
  *
14
16
  * ```ts
@@ -42,6 +44,20 @@
42
44
  * advertiseTools: true,
43
45
  * effects: "read",
44
46
  * });
47
+ *
48
+ * // named subset: advertise and call only these tools
49
+ * export default defineConnection({
50
+ * url: "https://mcp.example.com/inventory",
51
+ * advertiseTools: true,
52
+ * tools: ["search_skus", "get_stock"],
53
+ * });
54
+ *
55
+ * // drop a few tools from a large server
56
+ * export default defineConnection({
57
+ * url: "https://mcp.example.com/inventory",
58
+ * advertiseTools: true,
59
+ * disallowedTools: ["place_order", "delete_sku"],
60
+ * });
45
61
  * ```
46
62
  *
47
63
  * A **Cursor account MCP connection** exposes the MCP connectors the operator
@@ -129,6 +145,7 @@ export {
129
145
  isInlineStdioConnection,
130
146
  isToolEffect,
131
147
  normalizeConnectionEffects,
148
+ normalizeConnectionTools,
132
149
  normalizeCursorAccountServers,
133
150
  } from "./types.js";
134
151
 
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Cursor cloud agents as an extension. Mount it and the agent can hand
3
+ * coding work to Cursor cloud agents and steer a fleet of them:
4
+ *
5
+ * ```ts
6
+ * // agent/extensions/cloud.ts
7
+ * import cursorCloudAgents from "@cursor/july/extensions/cursor-cloud-agents";
8
+ *
9
+ * export default cursorCloudAgents({
10
+ * cloud: { repos: [{ url: "https://github.com/acme/api" }], autoCreatePR: true },
11
+ * });
12
+ * ```
13
+ *
14
+ * Contributes `cloud__launch`, `cloud__get`, `cloud__dump`, `cloud__reply`,
15
+ * `cloud__cancel`, `cloud__list` and the `cloud__handoff` skill (the
16
+ * namespace is the mount filename), the action vocabulary Sand's CloudAgent
17
+ * tool uses, over the same backend calls: launches through the v1 Cloud
18
+ * Agents API, everything else through the BackgroundComposerService RPCs,
19
+ * all under the serve host's Cursor API key (`CURSOR_API_KEY`, key file, or
20
+ * `login`). Each launched agent stays bound to the principal that launched
21
+ * it, and launches go to the configured repositories. The tools run on the
22
+ * serve host, so they need the local runtime.
23
+ */
24
+
25
+ import { z } from "zod";
26
+ import { defineExtension } from "../../extensions.js";
27
+ import type {
28
+ AgentCloudOptions,
29
+ Extension,
30
+ ModelSetting,
31
+ } from "../../types.js";
32
+
33
+ /** Mount options; every field is optional. */
34
+ export interface CursorCloudAgentsOptions {
35
+ /**
36
+ * Launch defaults: target `repos`, `env`, `autoCreatePR`, ... in the same
37
+ * vocabulary as `defineAgent({ cloud })`. Configured `repos` are also the
38
+ * allowlist for a launch's own `repo` / `prUrl`; model-chosen targets are
39
+ * refused when no allowlist is configured. With none configured,
40
+ * `needsApproval` defaults to true so prompt-only launches park first.
41
+ */
42
+ cloud?: AgentCloudOptions;
43
+ /** Model for launched agents. The account default when omitted. */
44
+ model?: ModelSetting;
45
+ /**
46
+ * Park launches and follow-ups for a human approval. Defaults to `true`
47
+ * when no `cloud.repos` are configured (prompt-only launches still use
48
+ * the host key); `false` once repositories are configured. Pass an
49
+ * explicit boolean to override. Model-chosen `repo` / `prUrl` still
50
+ * require the allowlist regardless of this flag.
51
+ */
52
+ needsApproval?: boolean;
53
+ /** Cursor API key. Defaults to the serve host's own key. */
54
+ apiKey?: string;
55
+ }
56
+
57
+ /** {@link CursorCloudAgentsOptions} with defaults applied. */
58
+ export interface CursorCloudAgentsConfig {
59
+ cloud: AgentCloudOptions;
60
+ model?: ModelSetting;
61
+ needsApproval: boolean;
62
+ apiKey?: string;
63
+ }
64
+
65
+ const repo = z.object({
66
+ url: z.string().url(),
67
+ startingRef: z.string().optional(),
68
+ prUrl: z.string().url().optional(),
69
+ });
70
+
71
+ const cloud: z.ZodType<AgentCloudOptions> = z.object({
72
+ env: z
73
+ .discriminatedUnion("type", [
74
+ z.object({ type: z.literal("cloud"), name: z.string().optional() }),
75
+ z.object({ type: z.literal("pool"), name: z.string().optional() }),
76
+ z.object({ type: z.literal("machine"), name: z.string().optional() }),
77
+ ])
78
+ .optional(),
79
+ repos: z.array(repo).optional(),
80
+ workOnCurrentBranch: z.boolean().optional(),
81
+ autoCreatePR: z.boolean().optional(),
82
+ skipReviewerRequest: z.boolean().optional(),
83
+ envVars: z.record(z.string()).optional(),
84
+ });
85
+
86
+ const model: z.ZodType<ModelSetting> = z.union([
87
+ z.string().min(1),
88
+ z.object({
89
+ id: z.string().min(1),
90
+ params: z.array(z.object({ id: z.string(), value: z.string() })).optional(),
91
+ }),
92
+ ]);
93
+
94
+ const config: z.ZodType<
95
+ CursorCloudAgentsConfig,
96
+ z.ZodTypeDef,
97
+ CursorCloudAgentsOptions | undefined
98
+ > = z
99
+ .object({
100
+ cloud: cloud.default({}),
101
+ model: model.optional(),
102
+ needsApproval: z.boolean().optional(),
103
+ apiKey: z.string().optional(),
104
+ })
105
+ .default({})
106
+ .transform((options) => ({
107
+ ...options,
108
+ needsApproval: options.needsApproval ?? options.cloud.repos === undefined,
109
+ }));
110
+
111
+ const cursorCloudAgents: Extension<
112
+ CursorCloudAgentsConfig,
113
+ CursorCloudAgentsOptions | undefined
114
+ > = defineExtension({
115
+ root: import.meta.dirname,
116
+ description: "Launch, steer, and monitor Cursor cloud agents.",
117
+ config,
118
+ });
119
+
120
+ export default cursorCloudAgents;
@@ -0,0 +1,395 @@
1
+ /**
2
+ * The Cursor backend as the tools use it: launches go through the public
3
+ * v1 Cloud Agents API (the only surface that takes per-launch `envVars`),
4
+ * everything about an existing agent goes through the same
5
+ * `aiserver.v1.BackgroundComposerService` RPCs Sand's CloudAgent tool
6
+ * calls, so follow-ups queue, runs pause, and the full conversation is
7
+ * readable. Both authenticate with the host's Cursor API key; the RPCs
8
+ * exchange it for a session token the way the dashboard client does.
9
+ */
10
+
11
+ import { randomUUID } from "node:crypto";
12
+ import { z } from "zod";
13
+ import { CursorBackendClient } from "../../../internal/cursor/backend-client.js";
14
+ import {
15
+ cursorBackendUrl,
16
+ cursorExternalApiUrl,
17
+ cursorWebsiteUrl,
18
+ resolveApiKeySync,
19
+ SIGN_IN_HINT,
20
+ } from "../../../internal/cursor/credentials.js";
21
+ import { toModelSelection } from "../../../internal/sdk-runner.js";
22
+ import type { AgentCloudOptions, ModelSetting } from "../../../types.js";
23
+ import extension from "../extension.js";
24
+
25
+ const SERVICE = "BackgroundComposerService";
26
+ /** Launches and follow-ups from this extension carry the SDK source, like the v1 API. */
27
+ const SOURCE = "BACKGROUND_COMPOSER_SOURCE_SDK";
28
+ const RPC_TIMEOUT_MS = 60_000;
29
+ // The create call returns once the initial run exists, which can wait on a VM.
30
+ const LAUNCH_TIMEOUT_MS = 300_000;
31
+
32
+ export class CloudAgentsApiError extends Error {
33
+ constructor(
34
+ message: string,
35
+ readonly status?: number
36
+ ) {
37
+ super(message);
38
+ this.name = "CloudAgentsApiError";
39
+ }
40
+ }
41
+
42
+ export type CloudAgentStatus =
43
+ | "creating"
44
+ | "running"
45
+ | "finished"
46
+ | "error"
47
+ | "expired"
48
+ | "unknown";
49
+
50
+ // Type aliases, not interfaces: these flow into tool results.
51
+ export type CloudAgentInfo = {
52
+ agentId: string;
53
+ name: string;
54
+ status: CloudAgentStatus;
55
+ archived: boolean;
56
+ url: string;
57
+ branch?: string;
58
+ prUrl?: string;
59
+ summary?: string;
60
+ error?: string;
61
+ changes?: { filesChanged: number; linesAdded: number; linesRemoved: number };
62
+ };
63
+
64
+ export type CloudAgentToolCall = {
65
+ name: string;
66
+ args: unknown;
67
+ content?: string;
68
+ error?: string;
69
+ };
70
+
71
+ export type CloudAgentMessage = {
72
+ role: "user" | "assistant";
73
+ text?: string;
74
+ thinking?: string;
75
+ toolCalls?: CloudAgentToolCall[];
76
+ };
77
+
78
+ export type CloudAgentLaunch = {
79
+ agentId: string;
80
+ runId: string;
81
+ status: string;
82
+ url: string;
83
+ };
84
+
85
+ export type LaunchRequest = {
86
+ prompt: string;
87
+ name?: string;
88
+ cloud: AgentCloudOptions;
89
+ model?: ModelSetting;
90
+ };
91
+
92
+ // ---------------------------------------------------------------------------
93
+ // Proto-JSON response schemas (camelCase; default-valued fields are omitted)
94
+ // ---------------------------------------------------------------------------
95
+
96
+ const composerSchema = z.object({
97
+ bcId: z.string(),
98
+ name: z.string().optional(),
99
+ status: z.string().optional(),
100
+ isArchived: z.boolean().optional(),
101
+ branchName: z.string().optional(),
102
+ prUrl: z.string().optional(),
103
+ linesAdded: z.number().optional(),
104
+ linesRemoved: z.number().optional(),
105
+ filesChanged: z.number().optional(),
106
+ });
107
+
108
+ const errorDetailsSchema = z.object({
109
+ details: z
110
+ .object({ title: z.string().optional(), detail: z.string().optional() })
111
+ .optional(),
112
+ });
113
+
114
+ const infoResponseSchema = z.object({
115
+ composer: z.object({
116
+ composer: composerSchema,
117
+ summary: z.string().optional(),
118
+ startError: errorDetailsSchema.optional(),
119
+ permanentError: errorDetailsSchema.optional(),
120
+ }),
121
+ });
122
+
123
+ const toolResultSchema = z.object({
124
+ toolName: z.string().optional(),
125
+ args: z.string().optional(),
126
+ rawArgs: z.string().optional(),
127
+ content: z.string().optional(),
128
+ error: z
129
+ .object({ clientVisibleErrorMessage: z.string().optional() })
130
+ .optional(),
131
+ });
132
+
133
+ const conversationResponseSchema = z.object({
134
+ conversation: z
135
+ .array(
136
+ z.object({
137
+ type: z.string().optional(),
138
+ text: z.string().optional(),
139
+ thinking: z.object({ text: z.string().optional() }).optional(),
140
+ toolResults: z.array(toolResultSchema).optional(),
141
+ })
142
+ )
143
+ .optional(),
144
+ });
145
+
146
+ const followupResponseSchema = z.object({ runId: z.string().optional() });
147
+
148
+ const launchResponseSchema = z.object({
149
+ agent: z.object({ id: z.string(), url: z.string().optional() }),
150
+ run: z.object({ id: z.string(), status: z.string() }),
151
+ });
152
+
153
+ // ---------------------------------------------------------------------------
154
+
155
+ export class CloudAgentsBackend {
156
+ private readonly rpcClient: CursorBackendClient;
157
+
158
+ constructor(
159
+ private readonly apiKey: () => string,
160
+ private readonly fetchImpl: typeof fetch = fetch
161
+ ) {
162
+ // The key is read per call: the host can sign in after the mount.
163
+ this.rpcClient = new CursorBackendClient({
164
+ backendUrl: cursorBackendUrl(),
165
+ apiKey: "",
166
+ getApiKey: apiKey,
167
+ fetchImpl,
168
+ });
169
+ }
170
+
171
+ /** `POST /v1/agents`: create the agent and start its first run in one call. */
172
+ async launch(request: LaunchRequest): Promise<CloudAgentLaunch> {
173
+ const { cloud } = request;
174
+ const body = {
175
+ prompt: { text: request.prompt },
176
+ name: request.name,
177
+ model:
178
+ request.model === undefined
179
+ ? undefined
180
+ : toModelSelection(request.model),
181
+ env: cloud.env,
182
+ envVars: cloud.envVars,
183
+ repos: cloud.repos,
184
+ workOnCurrentBranch: cloud.workOnCurrentBranch,
185
+ autoCreatePR: cloud.autoCreatePR,
186
+ skipReviewerRequest: cloud.skipReviewerRequest,
187
+ };
188
+ let response: Response;
189
+ try {
190
+ response = await this.fetchImpl(`${cursorExternalApiUrl()}/v1/agents`, {
191
+ method: "POST",
192
+ headers: {
193
+ "content-type": "application/json",
194
+ authorization: `Bearer ${this.apiKey()}`,
195
+ "x-ghost-mode": "true",
196
+ "x-cursor-client-type": "agent-serve",
197
+ "x-request-id": randomUUID(),
198
+ },
199
+ body: JSON.stringify(body),
200
+ signal: AbortSignal.timeout(LAUNCH_TIMEOUT_MS),
201
+ });
202
+ } catch (error) {
203
+ throw new CloudAgentsApiError(
204
+ `Cloud agent launch failed: ${error instanceof Error ? error.message : String(error)}`
205
+ );
206
+ }
207
+ const text = await response.text();
208
+ if (!response.ok) {
209
+ throw new CloudAgentsApiError(
210
+ `Cloud agent launch failed (${response.status}): ${apiErrorMessage(text)}`,
211
+ response.status
212
+ );
213
+ }
214
+ const parsed = launchResponseSchema.parse(JSON.parse(text));
215
+ return {
216
+ agentId: parsed.agent.id,
217
+ runId: parsed.run.id,
218
+ status: parsed.run.status.toLowerCase(),
219
+ url: parsed.agent.url ?? agentUrl(parsed.agent.id),
220
+ };
221
+ }
222
+
223
+ async info(agentId: string): Promise<CloudAgentInfo> {
224
+ const { composer } = infoResponseSchema.parse(
225
+ await this.rpcClient.serviceRpc(
226
+ SERVICE,
227
+ "GetBackgroundComposerInfo",
228
+ { bcId: agentId },
229
+ RPC_TIMEOUT_MS
230
+ )
231
+ );
232
+ const { composer: summary } = composer;
233
+ const failure = composer.permanentError ?? composer.startError;
234
+ return {
235
+ agentId: summary.bcId,
236
+ name: summary.name ?? "",
237
+ status: statusOf(summary.status),
238
+ archived: summary.isArchived === true,
239
+ url: agentUrl(summary.bcId),
240
+ branch: emptyToUndefined(summary.branchName),
241
+ prUrl: emptyToUndefined(summary.prUrl),
242
+ summary: emptyToUndefined(composer.summary),
243
+ error: failureMessage(failure),
244
+ changes:
245
+ summary.filesChanged === undefined
246
+ ? undefined
247
+ : {
248
+ filesChanged: summary.filesChanged,
249
+ linesAdded: summary.linesAdded ?? 0,
250
+ linesRemoved: summary.linesRemoved ?? 0,
251
+ },
252
+ };
253
+ }
254
+
255
+ async conversation(agentId: string): Promise<CloudAgentMessage[]> {
256
+ const { conversation } = conversationResponseSchema.parse(
257
+ await this.rpcClient.serviceRpc(
258
+ SERVICE,
259
+ "GetBackgroundComposerConversation",
260
+ { bcId: agentId },
261
+ RPC_TIMEOUT_MS
262
+ )
263
+ );
264
+ return (conversation ?? []).map((message) => {
265
+ const toolCalls = (message.toolResults ?? []).map((result) => ({
266
+ name: result.toolName ?? "",
267
+ args: parseArgs(result.args ?? result.rawArgs),
268
+ content: result.content,
269
+ error: result.error?.clientVisibleErrorMessage,
270
+ }));
271
+ return {
272
+ role: message.type === "MESSAGE_TYPE_HUMAN" ? "user" : "assistant",
273
+ text: emptyToUndefined(message.text),
274
+ thinking: emptyToUndefined(message.thinking?.text),
275
+ toolCalls: toolCalls.length === 0 ? undefined : toolCalls,
276
+ };
277
+ });
278
+ }
279
+
280
+ /**
281
+ * Queue a follow-up behind the current run, or with `interrupt` cancel the
282
+ * in-flight step and run it now; the backend's `synchronous` switch.
283
+ */
284
+ async followUp(
285
+ agentId: string,
286
+ prompt: string,
287
+ interrupt: boolean
288
+ ): Promise<{ runId: string | undefined }> {
289
+ const { runId } = followupResponseSchema.parse(
290
+ await this.rpcClient.serviceRpc(
291
+ SERVICE,
292
+ "AddAsyncFollowupBackgroundComposer",
293
+ {
294
+ bcId: agentId,
295
+ synchronous: interrupt,
296
+ followupSource: SOURCE,
297
+ followupMessage: {
298
+ text: prompt,
299
+ type: "MESSAGE_TYPE_HUMAN",
300
+ bubbleId: randomUUID(),
301
+ },
302
+ },
303
+ RPC_TIMEOUT_MS
304
+ )
305
+ );
306
+ return { runId };
307
+ }
308
+
309
+ async pause(agentId: string): Promise<void> {
310
+ await this.rpcClient.serviceRpc(
311
+ SERVICE,
312
+ "PauseBackgroundComposer",
313
+ { bcId: agentId, source: SOURCE },
314
+ RPC_TIMEOUT_MS
315
+ );
316
+ }
317
+ }
318
+
319
+ let backend: CloudAgentsBackend | undefined;
320
+
321
+ /** The process-wide backend for this mount, built on first use. */
322
+ export function cloudAgentsBackend(): CloudAgentsBackend {
323
+ backend ??= new CloudAgentsBackend(apiKey);
324
+ return backend;
325
+ }
326
+
327
+ export function apiKey(): string {
328
+ const key = resolveApiKeySync({ apiKey: extension.config.apiKey });
329
+ if (key === undefined) {
330
+ throw new Error(`Cloud agents need a Cursor API key. ${SIGN_IN_HINT}`);
331
+ }
332
+ return key.apiKey;
333
+ }
334
+
335
+ export function agentUrl(agentId: string): string {
336
+ return `${cursorWebsiteUrl()}/agents/${agentId}`;
337
+ }
338
+
339
+ function statusOf(status: string | undefined): CloudAgentStatus {
340
+ switch (status) {
341
+ case "BACKGROUND_COMPOSER_STATUS_CREATING":
342
+ return "creating";
343
+ case "BACKGROUND_COMPOSER_STATUS_RUNNING":
344
+ return "running";
345
+ case "BACKGROUND_COMPOSER_STATUS_FINISHED":
346
+ return "finished";
347
+ case "BACKGROUND_COMPOSER_STATUS_ERROR":
348
+ return "error";
349
+ case "BACKGROUND_COMPOSER_STATUS_EXPIRED":
350
+ return "expired";
351
+ default:
352
+ return "unknown";
353
+ }
354
+ }
355
+
356
+ function failureMessage(
357
+ failure: z.infer<typeof errorDetailsSchema> | undefined
358
+ ): string | undefined {
359
+ const parts = [failure?.details?.title, failure?.details?.detail].filter(
360
+ (part): part is string => part !== undefined && part !== ""
361
+ );
362
+ return parts.length === 0 ? undefined : parts.join(": ");
363
+ }
364
+
365
+ function parseArgs(args: string | undefined): unknown {
366
+ if (args === undefined || args === "") {
367
+ return undefined;
368
+ }
369
+ try {
370
+ return JSON.parse(args) as unknown;
371
+ } catch {
372
+ return args;
373
+ }
374
+ }
375
+
376
+ function emptyToUndefined(value: string | undefined): string | undefined {
377
+ return value === undefined || value === "" ? undefined : value;
378
+ }
379
+
380
+ function apiErrorMessage(text: string): string {
381
+ try {
382
+ const parsed = JSON.parse(text) as {
383
+ error?: { code?: string; message?: string };
384
+ code?: string;
385
+ message?: string;
386
+ };
387
+ const code = parsed.error?.code ?? parsed.code;
388
+ const message = parsed.error?.message ?? parsed.message;
389
+ return (
390
+ [code, message].filter((part) => part !== undefined).join(": ") || text
391
+ );
392
+ } catch {
393
+ return text;
394
+ }
395
+ }