@cursor/july 0.1.99 → 0.1.101

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 (420) hide show
  1. package/AGENTS.md +4 -2
  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/github/defaults.d.ts.map +1 -1
  9. package/dist/channels/github/defaults.js +28 -3
  10. package/dist/channels/github/progress.d.ts +7 -0
  11. package/dist/channels/github/progress.d.ts.map +1 -1
  12. package/dist/channels/origin/defaults.d.ts +43 -0
  13. package/dist/channels/origin/defaults.d.ts.map +1 -0
  14. package/dist/channels/origin/defaults.js +111 -0
  15. package/dist/channels/origin/index.d.ts +2 -0
  16. package/dist/channels/origin/index.d.ts.map +1 -1
  17. package/dist/channels/origin/index.js +2 -0
  18. package/dist/channels/origin/origin-channel.d.ts +2 -1
  19. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  20. package/dist/channels/origin/origin-channel.js +24 -3
  21. package/dist/channels/origin/state.d.ts +32 -0
  22. package/dist/channels/origin/state.d.ts.map +1 -0
  23. package/dist/channels/origin/state.js +23 -0
  24. package/dist/channels/origin/types.d.ts +23 -1
  25. package/dist/channels/origin/types.d.ts.map +1 -1
  26. package/dist/channels/slack/api.d.ts +16 -7
  27. package/dist/channels/slack/api.d.ts.map +1 -1
  28. package/dist/channels/slack/api.js +31 -14
  29. package/dist/channels/slack/code-fences.d.ts +17 -0
  30. package/dist/channels/slack/code-fences.d.ts.map +1 -0
  31. package/dist/channels/slack/code-fences.js +168 -0
  32. package/dist/channels/slack/constants.d.ts +6 -0
  33. package/dist/channels/slack/constants.d.ts.map +1 -1
  34. package/dist/channels/slack/constants.js +6 -0
  35. package/dist/channels/slack/defaults.d.ts +9 -4
  36. package/dist/channels/slack/defaults.d.ts.map +1 -1
  37. package/dist/channels/slack/defaults.js +154 -76
  38. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  39. package/dist/channels/slack/dispatch.js +3 -3
  40. package/dist/channels/slack/inbound.d.ts +9 -0
  41. package/dist/channels/slack/inbound.d.ts.map +1 -1
  42. package/dist/channels/slack/inbound.js +14 -0
  43. package/dist/channels/slack/index.d.ts +2 -0
  44. package/dist/channels/slack/index.d.ts.map +1 -1
  45. package/dist/channels/slack/index.js +2 -0
  46. package/dist/channels/slack/live-delivery.d.ts +5 -0
  47. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  48. package/dist/channels/slack/live-delivery.js +116 -21
  49. package/dist/channels/slack/reasoning-card.d.ts +38 -0
  50. package/dist/channels/slack/reasoning-card.d.ts.map +1 -0
  51. package/dist/channels/slack/reasoning-card.js +104 -0
  52. package/dist/channels/slack/redact.d.ts +2 -0
  53. package/dist/channels/slack/redact.d.ts.map +1 -0
  54. package/dist/channels/slack/redact.js +5 -0
  55. package/dist/channels/slack/reply-options.d.ts +40 -0
  56. package/dist/channels/slack/reply-options.d.ts.map +1 -0
  57. package/dist/channels/slack/reply-options.js +150 -0
  58. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  59. package/dist/channels/slack/slack-channel.js +8 -4
  60. package/dist/channels/slack/stream.d.ts +22 -10
  61. package/dist/channels/slack/stream.d.ts.map +1 -1
  62. package/dist/channels/slack/stream.js +9 -16
  63. package/dist/channels/slack/tool-cards.d.ts +22 -0
  64. package/dist/channels/slack/tool-cards.d.ts.map +1 -0
  65. package/dist/channels/slack/tool-cards.js +178 -0
  66. package/dist/channels/slack/types.d.ts +145 -6
  67. package/dist/channels/slack/types.d.ts.map +1 -1
  68. package/dist/connections.d.ts +18 -2
  69. package/dist/connections.d.ts.map +1 -1
  70. package/dist/connections.js +18 -2
  71. package/dist/docs/404.html +2 -2
  72. package/dist/docs/ab.html +6 -6
  73. package/dist/docs/ab.md +1 -1
  74. package/dist/docs/assets/{ab.md.DJo5r4R-.js → ab.md.mlVgqvSk.js} +1 -1
  75. package/dist/docs/assets/{app.BplEAZ3S.js → app.BASO9Kih.js} +1 -1
  76. package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.js → building-with-agents.md.CUSWxlP_.js} +2 -2
  77. package/dist/docs/assets/chunks/@localSearchIndexroot.DbFXINq2.js +1 -0
  78. package/dist/docs/assets/chunks/{VPLocalSearchBox.CHXyv4wP.js → VPLocalSearchBox.DwkqxoE0.js} +1 -1
  79. package/dist/docs/assets/chunks/{theme.BTcsZmjQ.js → theme.CCil_13e.js} +2 -2
  80. package/dist/docs/assets/{evals.md.lfJoEVc8.js → evals.md.CPzDAwoH.js} +1 -1
  81. package/dist/docs/assets/{guides_github.md.Cnh2mL4a.js → guides_github.md.BtPr9GaP.js} +1 -1
  82. package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.js → guides_mcp-oauth.md.Dp6cDP7f.js} +1 -1
  83. package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.js → guides_opentelemetry.md.BVTXDCRg.js} +2 -2
  84. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.js → guides_slack.md.9oHPye9o.js} +19 -3
  85. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.lean.js → guides_slack.md.9oHPye9o.lean.js} +1 -1
  86. package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +4 -0
  87. package/dist/docs/assets/{index.md.CVeRUOeZ.js → index.md.Bb4k8kUm.js} +1 -1
  88. package/dist/docs/assets/{quickstart.md.Nj_LjW_a.js → quickstart.md.DdQOF7Y8.js} +1 -1
  89. package/dist/docs/assets/{reference_connections.md.DxldvyIB.js → reference_connections.md.Di6jJAXF.js} +13 -3
  90. package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.Di6jJAXF.lean.js} +1 -1
  91. package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.js → reference_http-api.md.oySXBO8o.js} +1 -1
  92. package/dist/docs/assets/scaffolding-agents.md.em43xlY1.js +1 -0
  93. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +26 -0
  94. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +1 -0
  95. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.js +8 -0
  96. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.lean.js +1 -0
  97. package/dist/docs/assets/skills_debug.md.CDbPhHfg.js +1 -0
  98. package/dist/docs/assets/skills_debug.md.CDbPhHfg.lean.js +1 -0
  99. package/dist/docs/assets/skills_evals.md.723kpUmA.js +25 -0
  100. package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +1 -0
  101. package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +1 -0
  102. package/dist/docs/assets/skills_framework-map.md.BTi817yv.lean.js +1 -0
  103. package/dist/docs/assets/skills_github.md.D0JahM8c.js +16 -0
  104. package/dist/docs/assets/skills_github.md.D0JahM8c.lean.js +1 -0
  105. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +7 -0
  106. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +1 -0
  107. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +1 -0
  108. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +1 -0
  109. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +18 -0
  110. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +1 -0
  111. package/dist/docs/assets/skills_otel.md.CgiZryR3.js +8 -0
  112. package/dist/docs/assets/skills_otel.md.CgiZryR3.lean.js +1 -0
  113. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +20 -0
  114. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +1 -0
  115. package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.js → troubleshooting.md.Cus_YZga.js} +1 -1
  116. package/dist/docs/building-with-agents.html +6 -6
  117. package/dist/docs/building-with-agents.md +14 -11
  118. package/dist/docs/concepts.html +4 -4
  119. package/dist/docs/deployment.html +4 -4
  120. package/dist/docs/evals.html +6 -6
  121. package/dist/docs/evals.md +1 -1
  122. package/dist/docs/guides/agent-to-agent.html +4 -4
  123. package/dist/docs/guides/cloud-runtime.html +4 -4
  124. package/dist/docs/guides/convert-automation.html +4 -4
  125. package/dist/docs/guides/github.html +5 -5
  126. package/dist/docs/guides/github.md +1 -1
  127. package/dist/docs/guides/human-in-the-loop.html +4 -4
  128. package/dist/docs/guides/mcp-oauth.html +5 -5
  129. package/dist/docs/guides/mcp-oauth.md +1 -1
  130. package/dist/docs/guides/opentelemetry.html +7 -7
  131. package/dist/docs/guides/opentelemetry.md +2 -2
  132. package/dist/docs/guides/slack.html +22 -6
  133. package/dist/docs/guides/slack.md +80 -1
  134. package/dist/docs/guides/webhooks.html +5 -5
  135. package/dist/docs/hashmap.json +1 -1
  136. package/dist/docs/hillclimbing.html +6 -6
  137. package/dist/docs/hillclimbing.md +5 -5
  138. package/dist/docs/index.html +6 -6
  139. package/dist/docs/index.md +1 -1
  140. package/dist/docs/llms-full.txt +1073 -31
  141. package/dist/docs/llms.txt +14 -0
  142. package/dist/docs/quickstart.html +5 -5
  143. package/dist/docs/quickstart.md +1 -1
  144. package/dist/docs/reference/agent-config.html +4 -4
  145. package/dist/docs/reference/artifacts.html +4 -4
  146. package/dist/docs/reference/channels.html +4 -4
  147. package/dist/docs/reference/cli.html +4 -4
  148. package/dist/docs/reference/connections.html +17 -7
  149. package/dist/docs/reference/connections.md +32 -1
  150. package/dist/docs/reference/hooks.html +4 -4
  151. package/dist/docs/reference/http-api.html +6 -6
  152. package/dist/docs/reference/http-api.md +1 -1
  153. package/dist/docs/reference/instructions.html +4 -4
  154. package/dist/docs/reference/playground.html +4 -4
  155. package/dist/docs/reference/project-layout.html +4 -4
  156. package/dist/docs/reference/prompt.html +4 -4
  157. package/dist/docs/reference/schedules.html +4 -4
  158. package/dist/docs/reference/sessions.html +4 -4
  159. package/dist/docs/reference/skills.html +4 -4
  160. package/dist/docs/reference/subagents.html +4 -4
  161. package/dist/docs/reference/tools.html +4 -4
  162. package/dist/docs/scaffolding-agents.html +5 -5
  163. package/dist/docs/scaffolding-agents.md +3 -3
  164. package/dist/docs/skills/ab.html +52 -0
  165. package/dist/docs/skills/ab.md +50 -0
  166. package/dist/docs/skills/create-agent.html +34 -0
  167. package/dist/docs/skills/create-agent.md +160 -0
  168. package/dist/docs/skills/debug.html +27 -0
  169. package/dist/docs/skills/debug.md +36 -0
  170. package/dist/docs/skills/evals.html +51 -0
  171. package/dist/docs/skills/evals.md +99 -0
  172. package/dist/docs/skills/framework-map.html +27 -0
  173. package/dist/docs/skills/framework-map.md +95 -0
  174. package/dist/docs/skills/github.html +42 -0
  175. package/dist/docs/skills/github.md +93 -0
  176. package/dist/docs/skills/hillclimb.html +33 -0
  177. package/dist/docs/skills/hillclimb.md +55 -0
  178. package/dist/docs/skills/index.html +27 -0
  179. package/dist/docs/skills/index.md +21 -0
  180. package/dist/docs/skills/mcp-auth.html +44 -0
  181. package/dist/docs/skills/mcp-auth.md +76 -0
  182. package/dist/docs/skills/otel.html +34 -0
  183. package/dist/docs/skills/otel.md +48 -0
  184. package/dist/docs/skills/setup-slack.html +46 -0
  185. package/dist/docs/skills/setup-slack.md +141 -0
  186. package/dist/docs/storage.html +4 -4
  187. package/dist/docs/templates/agentic-owners.html +4 -4
  188. package/dist/docs/templates/agents-md.html +4 -4
  189. package/dist/docs/templates/code-wiki.html +4 -4
  190. package/dist/docs/templates/demo.html +4 -4
  191. package/dist/docs/templates/pr-autofixer.html +4 -4
  192. package/dist/docs/templates/security-help.html +4 -4
  193. package/dist/docs/templates/security-reviewer.html +4 -4
  194. package/dist/docs/templates/triage.html +4 -4
  195. package/dist/docs/troubleshooting.html +5 -5
  196. package/dist/docs/troubleshooting.md +1 -1
  197. package/dist/extensions/cursor-cloud-agents/extension.d.ts +55 -0
  198. package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -0
  199. package/dist/extensions/cursor-cloud-agents/extension.js +64 -0
  200. package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts +30 -0
  201. package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts.map +1 -0
  202. package/dist/extensions/cursor-cloud-agents/lib/cloud.js +45 -0
  203. package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts +25 -0
  204. package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts.map +1 -0
  205. package/dist/extensions/cursor-cloud-agents/lib/fleet.js +85 -0
  206. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +15 -0
  207. package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -0
  208. package/dist/extensions/cursor-cloud-agents/lib/repos.js +55 -0
  209. package/dist/extensions/cursor-cloud-agents/skills/handoff.md +27 -0
  210. package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts +4 -0
  211. package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts.map +1 -0
  212. package/dist/extensions/cursor-cloud-agents/tools/follow_up.js +37 -0
  213. package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts +4 -0
  214. package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -0
  215. package/dist/extensions/cursor-cloud-agents/tools/launch.js +83 -0
  216. package/dist/extensions/cursor-cloud-agents/tools/list.d.ts +4 -0
  217. package/dist/extensions/cursor-cloud-agents/tools/list.d.ts.map +1 -0
  218. package/dist/extensions/cursor-cloud-agents/tools/list.js +36 -0
  219. package/dist/extensions/cursor-cloud-agents/tools/status.d.ts +4 -0
  220. package/dist/extensions/cursor-cloud-agents/tools/status.d.ts.map +1 -0
  221. package/dist/extensions/cursor-cloud-agents/tools/status.js +41 -0
  222. package/dist/extensions.d.ts +49 -0
  223. package/dist/extensions.d.ts.map +1 -0
  224. package/dist/extensions.js +75 -0
  225. package/dist/files-backends/cursor-hosted.d.ts +6 -0
  226. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  227. package/dist/files-backends/cursor-hosted.js +6 -9
  228. package/dist/index.d.ts +2 -1
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +2 -1
  231. package/dist/internal/advertise-tools.d.ts +4 -1
  232. package/dist/internal/advertise-tools.d.ts.map +1 -1
  233. package/dist/internal/advertise-tools.js +20 -1
  234. package/dist/internal/as-of.d.ts +18 -0
  235. package/dist/internal/as-of.d.ts.map +1 -1
  236. package/dist/internal/as-of.js +131 -0
  237. package/dist/internal/cli-deploy.d.ts.map +1 -1
  238. package/dist/internal/cli-deploy.js +66 -21
  239. package/dist/internal/continuation-identity.d.ts.map +1 -1
  240. package/dist/internal/continuation-identity.js +3 -1
  241. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  242. package/dist/internal/conversation-mirror.js +3 -4
  243. package/dist/internal/cursor/hosted-deployment-secrets.d.ts +16 -0
  244. package/dist/internal/cursor/hosted-deployment-secrets.d.ts.map +1 -0
  245. package/dist/internal/cursor/hosted-deployment-secrets.js +61 -0
  246. package/dist/internal/cursor/hosted-store-secrets.d.ts +15 -0
  247. package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -0
  248. package/dist/internal/cursor/hosted-store-secrets.js +48 -0
  249. package/dist/internal/cursor-deployment-relay.d.ts +15 -1
  250. package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
  251. package/dist/internal/cursor-deployment-relay.js +46 -7
  252. package/dist/internal/deploy-client.d.ts +29 -6
  253. package/dist/internal/deploy-client.d.ts.map +1 -1
  254. package/dist/internal/deploy-client.js +61 -19
  255. package/dist/internal/discovery.d.ts.map +1 -1
  256. package/dist/internal/discovery.js +426 -121
  257. package/dist/internal/distribution.d.ts.map +1 -1
  258. package/dist/internal/distribution.js +5 -0
  259. package/dist/internal/framework-file-storage.d.ts +15 -8
  260. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  261. package/dist/internal/framework-file-storage.js +70 -10
  262. package/dist/internal/framework-storage-selection.d.ts +12 -12
  263. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  264. package/dist/internal/framework-storage-selection.js +33 -39
  265. package/dist/internal/hosted-delivery.d.ts +3 -1
  266. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  267. package/dist/internal/hosted-delivery.js +19 -32
  268. package/dist/internal/hosted-execution-diag.d.ts +5 -0
  269. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  270. package/dist/internal/hosted-execution-diag.js +5 -0
  271. package/dist/internal/hosted-execution-flush.d.ts +46 -0
  272. package/dist/internal/hosted-execution-flush.d.ts.map +1 -0
  273. package/dist/internal/hosted-execution-flush.js +81 -0
  274. package/dist/internal/mcp-endpoint.js +1 -0
  275. package/dist/internal/mcp-host.d.ts +2 -1
  276. package/dist/internal/mcp-host.d.ts.map +1 -1
  277. package/dist/internal/mcp-host.js +35 -15
  278. package/dist/internal/review-comments.d.ts +1 -1
  279. package/dist/internal/review-comments.d.ts.map +1 -1
  280. package/dist/internal/review-comments.js +4 -4
  281. package/dist/internal/server.d.ts +3 -0
  282. package/dist/internal/server.d.ts.map +1 -1
  283. package/dist/internal/server.js +79 -104
  284. package/dist/internal/session-engine.d.ts +9 -7
  285. package/dist/internal/session-engine.d.ts.map +1 -1
  286. package/dist/internal/session-engine.js +45 -34
  287. package/dist/internal/session-run-log.d.ts +5 -4
  288. package/dist/internal/session-run-log.d.ts.map +1 -1
  289. package/dist/internal/session-run-log.js +8 -8
  290. package/dist/internal/start-log-store.d.ts +60 -0
  291. package/dist/internal/start-log-store.d.ts.map +1 -0
  292. package/dist/internal/start-log-store.js +151 -0
  293. package/dist/internal/storage-coordinator.d.ts +0 -6
  294. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  295. package/dist/internal/storage-coordinator.js +1 -9
  296. package/dist/internal/tool-policy.d.ts +8 -0
  297. package/dist/internal/tool-policy.d.ts.map +1 -1
  298. package/dist/internal/tool-policy.js +19 -7
  299. package/dist/playground/assets/{index-jzNbJENa.js → index-BnNN1-EK.js} +45 -45
  300. package/dist/playground/assets/index-DBQCwFp0.css +1 -0
  301. package/dist/playground/index.html +2 -2
  302. package/dist/storage-backends/cursor-hosted-v2.d.ts +83 -0
  303. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -0
  304. package/dist/storage-backends/cursor-hosted-v2.js +164 -0
  305. package/dist/storage-backends/cursor-hosted.d.ts +6 -0
  306. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  307. package/dist/storage-backends/cursor-hosted.js +6 -1
  308. package/dist/storage-protocol.d.ts +24 -0
  309. package/dist/storage-protocol.d.ts.map +1 -1
  310. package/dist/storage-protocol.js +33 -0
  311. package/dist/storage.d.ts +1 -1
  312. package/dist/storage.d.ts.map +1 -1
  313. package/dist/storage.js +1 -1
  314. package/dist/types.d.ts +123 -6
  315. package/dist/types.d.ts.map +1 -1
  316. package/dist/types.js +29 -1
  317. package/docs/README.md +1 -1
  318. package/docs/ab.md +1 -1
  319. package/docs/building-with-agents.md +14 -11
  320. package/docs/evals.md +1 -1
  321. package/docs/guides/github.md +1 -1
  322. package/docs/guides/mcp-oauth.md +1 -1
  323. package/docs/guides/opentelemetry.md +2 -2
  324. package/docs/guides/slack.md +80 -1
  325. package/docs/hillclimbing.md +5 -5
  326. package/docs/quickstart.md +1 -1
  327. package/docs/reference/connections.md +32 -1
  328. package/docs/reference/http-api.md +1 -1
  329. package/docs/scaffolding-agents.md +3 -3
  330. package/docs/skills/index.md +26 -0
  331. package/docs/troubleshooting.md +1 -1
  332. package/package.json +18 -4
  333. package/src/bin/agent-serve.ts +11 -2
  334. package/src/channels/deployments/deployments-channel.ts +117 -8
  335. package/src/channels/deployments/types.ts +4 -3
  336. package/src/channels/github/defaults.ts +36 -3
  337. package/src/channels/github/progress.ts +7 -0
  338. package/src/channels/origin/defaults.ts +143 -0
  339. package/src/channels/origin/index.ts +2 -0
  340. package/src/channels/origin/origin-channel.ts +37 -1
  341. package/src/channels/origin/state.ts +54 -0
  342. package/src/channels/origin/types.ts +24 -0
  343. package/src/channels/slack/api.ts +37 -18
  344. package/src/channels/slack/code-fences.ts +183 -0
  345. package/src/channels/slack/constants.ts +6 -0
  346. package/src/channels/slack/defaults.ts +173 -92
  347. package/src/channels/slack/dispatch.ts +8 -1
  348. package/src/channels/slack/inbound.ts +17 -0
  349. package/src/channels/slack/index.ts +2 -0
  350. package/src/channels/slack/live-delivery.ts +142 -28
  351. package/src/channels/slack/reasoning-card.ts +140 -0
  352. package/src/channels/slack/redact.ts +6 -0
  353. package/src/channels/slack/reply-options.ts +229 -0
  354. package/src/channels/slack/slack-channel.ts +7 -2
  355. package/src/channels/slack/stream.ts +31 -24
  356. package/src/channels/slack/tool-cards.ts +221 -0
  357. package/src/channels/slack/types.ts +159 -6
  358. package/src/connections.ts +18 -1
  359. package/src/extensions/cursor-cloud-agents/extension.ts +118 -0
  360. package/src/extensions/cursor-cloud-agents/lib/cloud.ts +79 -0
  361. package/src/extensions/cursor-cloud-agents/lib/fleet.ts +109 -0
  362. package/src/extensions/cursor-cloud-agents/lib/repos.ts +81 -0
  363. package/src/extensions/cursor-cloud-agents/skills/handoff.md +27 -0
  364. package/src/extensions/cursor-cloud-agents/tools/follow_up.ts +29 -0
  365. package/src/extensions/cursor-cloud-agents/tools/launch.ts +84 -0
  366. package/src/extensions/cursor-cloud-agents/tools/list.ts +31 -0
  367. package/src/extensions/cursor-cloud-agents/tools/status.ts +39 -0
  368. package/src/extensions.ts +98 -0
  369. package/src/files-backends/cursor-hosted.ts +15 -5
  370. package/src/index.ts +2 -0
  371. package/src/internal/advertise-tools.ts +37 -12
  372. package/src/internal/as-of.ts +163 -0
  373. package/src/internal/cli-deploy.ts +88 -25
  374. package/src/internal/continuation-identity.ts +3 -1
  375. package/src/internal/conversation-mirror.ts +3 -8
  376. package/src/internal/cursor/hosted-deployment-secrets.ts +72 -0
  377. package/src/internal/cursor/hosted-store-secrets.ts +72 -0
  378. package/src/internal/cursor-deployment-relay.ts +65 -8
  379. package/src/internal/deploy-client.ts +83 -28
  380. package/src/internal/discovery.ts +479 -114
  381. package/src/internal/distribution.ts +5 -0
  382. package/src/internal/framework-file-storage.ts +80 -10
  383. package/src/internal/framework-storage-selection.ts +31 -44
  384. package/src/internal/hosted-delivery.ts +38 -63
  385. package/src/internal/hosted-execution-diag.ts +6 -0
  386. package/src/internal/hosted-execution-flush.ts +142 -0
  387. package/src/internal/mcp-endpoint.ts +1 -0
  388. package/src/internal/mcp-host.ts +40 -14
  389. package/src/internal/review-comments.ts +5 -2
  390. package/src/internal/server.ts +81 -100
  391. package/src/internal/session-engine.ts +56 -28
  392. package/src/internal/session-run-log.ts +8 -12
  393. package/src/internal/start-log-store.ts +177 -0
  394. package/src/internal/storage-coordinator.ts +1 -11
  395. package/src/internal/tool-policy.ts +39 -9
  396. package/src/storage-backends/cursor-hosted-v2.ts +219 -0
  397. package/src/storage-backends/cursor-hosted.ts +6 -1
  398. package/src/storage-protocol.ts +37 -0
  399. package/src/storage.ts +1 -0
  400. package/src/types.ts +177 -14
  401. package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +0 -1
  402. package/dist/docs/assets/hillclimbing.md.DhESf3OO.js +0 -4
  403. package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +0 -1
  404. package/dist/internal/null-kv-storage.d.ts +0 -48
  405. package/dist/internal/null-kv-storage.d.ts.map +0 -1
  406. package/dist/internal/null-kv-storage.js +0 -58
  407. package/dist/playground/assets/index-D7rGZNjy.css +0 -1
  408. package/src/internal/null-kv-storage.ts +0 -74
  409. /package/dist/docs/assets/{ab.md.DJo5r4R-.lean.js → ab.md.mlVgqvSk.lean.js} +0 -0
  410. /package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.lean.js → building-with-agents.md.CUSWxlP_.lean.js} +0 -0
  411. /package/dist/docs/assets/{evals.md.lfJoEVc8.lean.js → evals.md.CPzDAwoH.lean.js} +0 -0
  412. /package/dist/docs/assets/{guides_github.md.Cnh2mL4a.lean.js → guides_github.md.BtPr9GaP.lean.js} +0 -0
  413. /package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.lean.js → guides_mcp-oauth.md.Dp6cDP7f.lean.js} +0 -0
  414. /package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.lean.js → guides_opentelemetry.md.BVTXDCRg.lean.js} +0 -0
  415. /package/dist/docs/assets/{hillclimbing.md.DhESf3OO.lean.js → hillclimbing.md.CpTGTCle.lean.js} +0 -0
  416. /package/dist/docs/assets/{index.md.CVeRUOeZ.lean.js → index.md.Bb4k8kUm.lean.js} +0 -0
  417. /package/dist/docs/assets/{quickstart.md.Nj_LjW_a.lean.js → quickstart.md.DdQOF7Y8.lean.js} +0 -0
  418. /package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.lean.js → reference_http-api.md.oySXBO8o.lean.js} +0 -0
  419. /package/dist/docs/assets/{scaffolding-agents.md.D7UUkWw0.lean.js → scaffolding-agents.md.em43xlY1.lean.js} +0 -0
  420. /package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.lean.js → troubleshooting.md.Cus_YZga.lean.js} +0 -0
@@ -12,7 +12,7 @@ Replies stream there, with thinking steps and suggested prompts.
12
12
  Use `agent-sdk slack create` when Cursor should own the Slack app. Use
13
13
  `agent-sdk slack init --manual` when you own it. Commands and flags live
14
14
  in the [CLI reference](../reference/cli.md#slack). Coding agents should
15
- follow [`skills/setup-slack/SKILL.md`](../../skills/setup-slack/SKILL.md).
15
+ follow [`skills/setup-slack/SKILL.md`](../skills/setup-slack.md).
16
16
 
17
17
  ## Define the channel
18
18
 
@@ -55,6 +55,85 @@ export default slackChannel({
55
55
  });
56
56
  ```
57
57
 
58
+ ## Choose how the reply arrives
59
+
60
+ Slack gives an agent two places to show progress while a turn runs: the
61
+ status chip under the thread ("Running grep…") and the reply message
62
+ itself. It won't fill both at once. While a message is streaming, Slack
63
+ shows its own "is working…" chip and hides any status text you set. Cards
64
+ only exist inside a streamed message. `reply.mode` picks which one you get.
65
+
66
+ ### `post` (default): status chip, then one message
67
+
68
+ Tool calls and the first line of each reasoning block show in the chip as
69
+ they happen. The answer lands as a single message when the turn finishes.
70
+
71
+ ```ts
72
+ export default slackChannel({
73
+ reply: {
74
+ mode: "post",
75
+ status: {
76
+ reasoning: true,
77
+ tools: true,
78
+ idle: ["Checking the monorepo…", "Poking Datadog…"],
79
+ },
80
+ },
81
+ });
82
+ ```
83
+
84
+ `idle` is the rotation Slack cycles through when nothing more specific is
85
+ known, up to 5 lines of 50 characters. Pass a function to `tools` to write
86
+ your own line from the calls in flight.
87
+
88
+ ### `stream`: live text, with cards
89
+
90
+ The answer streams into one message as the model writes it. Slack owns the
91
+ chip for the duration, so live feedback inside the message comes from
92
+ cards. Both are off unless you turn them on.
93
+
94
+ ```ts
95
+ export default slackChannel({
96
+ reply: {
97
+ mode: "stream",
98
+ reasoningCard: true,
99
+ toolCards: { group: "per-tool" },
100
+ },
101
+ toolLabels: { grep: "Searching code", read: "Reading files" },
102
+ });
103
+ ```
104
+
105
+ The reasoning card is one task card, titled "Thinking", that receives the
106
+ model's reasoning as it streams and completes when the answer text starts.
107
+ `maxChars` (default 1500) caps how much it collects. Slack caps a streamed
108
+ message near 12k characters including cards; when an answer outgrows that,
109
+ the streamed message closes where it stands and the rest continues in a
110
+ new message.
111
+
112
+ Tool cards default to one card per tool name with a call count in the title
113
+ (`grep ×3`), updated in place as calls finish. `group: "per-call"` shows one
114
+ card per call instead.
115
+
116
+ Cards are collapsible by default: each call adds one line under the title,
117
+ the same summary the playground shows in a tool's header (the grep pattern,
118
+ the file path, the shell command), and the group expands the same way the
119
+ reasoning card does. `collapsible: false` keeps cards to their titles. On a
120
+ collapsible card, `details(call)` returns the line to add when a call starts
121
+ and `output(result)` the text to add when it finishes.
122
+
123
+ `toolLabels` renames tools everywhere they appear: the chip, card titles,
124
+ and the default `Running …` line.
125
+
126
+ ### Migrating from `streaming` and `thinkingSteps`
127
+
128
+ `streaming: false` is `reply: { mode: "post" }`. `streaming: true` is
129
+ `reply: { mode: "stream", toolCards: { group: "per-call", collapsible:
130
+ false } }`, the title-only cards it used to show. `loadingMessages` moves
131
+ to `reply.status.idle`. The old options still work and `agent-sdk validate`
132
+ prints the rewrite for each one.
133
+
134
+ A channel that set none of these used to stream. It now posts. Set
135
+ `reply: { mode: "stream" }` to keep streaming.
136
+
58
137
  ## Set it up
59
138
 
60
139
  `slack create` opens the Cursor dashboard wizard. Finish Slack consent
@@ -22,7 +22,7 @@ flowchart LR
22
22
 
23
23
  ## How do I hillclimb an agent with a coding agent?
24
24
 
25
- Have Cursor read [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md).
25
+ Have Cursor read [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md).
26
26
 
27
27
  Tell it:
28
28
 
@@ -36,10 +36,10 @@ Other skills cover the edges:
36
36
 
37
37
  | When you need… | Skill |
38
38
  | --- | --- |
39
- | The measured improvement loop | [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md) |
40
- | An eval that locks a kept win | [`skills/evals/SKILL.md`](../skills/evals/SKILL.md) |
41
- | Repeatable GitHub webhook inputs | [`skills/github/SKILL.md`](../skills/github/SKILL.md) |
42
- | A run that misbehaves | [`skills/debug/SKILL.md`](../skills/debug/SKILL.md) |
39
+ | The measured improvement loop | [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md) |
40
+ | An eval that locks a kept win | [`skills/evals/SKILL.md`](./skills/evals.md) |
41
+ | Repeatable GitHub webhook inputs | [`skills/github/SKILL.md`](./skills/github.md) |
42
+ | A run that misbehaves | [`skills/debug/SKILL.md`](./skills/debug.md) |
43
43
 
44
44
  See [Building agents with agents](./building-with-agents.md) for every framework skill and a good first prompt.
45
45
 
@@ -13,7 +13,7 @@ review. Add GitHub event handling so pull requests can trigger reviews.
13
13
 
14
14
  - **Get started with an agent in Cursor:** follow
15
15
  [Scaffold an agent with Cursor](./scaffolding-agents.md) and ask Cursor
16
- to read [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md).
16
+ to read [`skills/create-agent/SKILL.md`](./skills/create-agent.md).
17
17
  - **Get started in the CLI:** continue below.
18
18
 
19
19
  ## Prerequisites
@@ -54,7 +54,7 @@ agent-sdk mcp oauth inventory --store # also upsert deployment secrets
54
54
  ```
55
55
 
56
56
  Full walkthrough: [Host MCP OAuth](../guides/mcp-oauth.md). Companion
57
- skill: [`skills/mcp-auth/SKILL.md`](../../skills/mcp-auth/SKILL.md).
57
+ skill: [`skills/mcp-auth/SKILL.md`](../skills/mcp-auth.md).
58
58
 
59
59
  Account MCP (`cursorAccount: true`) is the right choice for connectors
60
60
  already linked in the Cursor dashboard. Omit `servers` (or pass `"*"`)
@@ -124,6 +124,37 @@ be called through the direct tool API.
124
124
  In a dry-run session, MCP tools marked read-only run normally. Tools marked
125
125
  as writes are stubbed. Tools without effect annotations are unavailable.
126
126
 
127
+ ## Restrict which tools a connection serves
128
+
129
+ Use `tools` the same way you allowlist harness tools on the agent. When
130
+ set, the connection serves only those names. Use `disallowedTools` to
131
+ drop names instead. The two combine as deny-wins, same as the Cursor
132
+ SDK. The model and `host.mcp` only see what remains. On a model-visible
133
+ connection, set `advertiseTools: true` so the raw server is not attached.
134
+
135
+ ```ts
136
+ export default defineConnection({
137
+ url: "https://mcp.example.com/inventory",
138
+ advertiseTools: true,
139
+ tools: ["search_skus", "get_stock"],
140
+ });
141
+
142
+ export default defineConnection({
143
+ url: "https://mcp.example.com/inventory",
144
+ advertiseTools: true,
145
+ disallowedTools: ["place_order", "delete_sku"],
146
+ });
147
+ ```
148
+
149
+ Names are the server's `tools/list` names. Unknown names are omitted. A
150
+ filter that matches nothing on the server fails the turn. Combine with
151
+ `effects: "read"` to keep only the listed tools the server classifies as
152
+ reads.
153
+
154
+ A list of names is an allowlist. An object of handlers authors TypeScript
155
+ tools. On `host-connections/`, a name list restricts `host.mcp` without
156
+ advertising.
157
+
127
158
  ## Local stdio MCP server
128
159
 
129
160
  Run a local MCP server as a child process with `command`.
@@ -53,7 +53,7 @@ and `playgroundUrl` deep-links the session in the playground.
53
53
  | `message` | Required user message |
54
54
  | `title` | Session title |
55
55
  | `dryRun` | Run read tools and stub write tools |
56
- | `asOf` | ISO-8601 instant with a timezone, frozen at create; the prompt states it, `ctx.now()` returns it, and tools declaring `timeArgs` refuse calls not bounded at or before it. `400` when unusable |
56
+ | `asOf` | ISO-8601 instant with a timezone, frozen at create; the prompt states it, `ctx.now()` returns it, and tool calls with relative, later-than-`asOf`, or omitted schema-declared time bounds are refused. `400` when unusable |
57
57
  | `workspaceFiles` | UTF-8 files written into the session workspace |
58
58
  | `cloud` | Per-session cloud options merged over the agent defaults |
59
59
 
@@ -11,7 +11,7 @@ decision.
11
11
  ## What does the create-agent skill do?
12
12
 
13
13
  The bundled
14
- [`create-agent` skill](../skills/create-agent/SKILL.md) turns your goal
14
+ [`create-agent` skill](./skills/create-agent.md) turns your goal
15
15
  into a small working project. Have Cursor read that file and follow it.
16
16
 
17
17
  Where to find the file depends on how you got the package:
@@ -26,7 +26,7 @@ Where to find the file depends on how you got the package:
26
26
  - Installed `@cursor/july` as a dependency? The skill also ships inside
27
27
  the package at `node_modules/@cursor/july/skills/create-agent/SKILL.md`.
28
28
  - Working from this package's source? The skill is at
29
- [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md). Run
29
+ [`skills/create-agent/SKILL.md`](./skills/create-agent.md). Run
30
30
  `agent-sdk install-skills` if you want the same copies in
31
31
  `~/.cursor/skills/agentsdk/` (the package postinstall skips the
32
32
  source checkout).
@@ -119,7 +119,7 @@ without a Cursor credential. Model turns and evals need
119
119
 
120
120
  Choose one to three fixed inputs, define what should improve, and name
121
121
  what must stay unchanged. Then have Cursor follow
122
- [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md).
122
+ [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md).
123
123
 
124
124
  The hillclimb skill measures a baseline, changes one lever, runs the same
125
125
  inputs again, and adds an eval for each improvement you keep.
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: "Coding-agent skills"
3
+ description: "Task guides that ship with the Agent SDK for scaffolding, evals, channels, and hillclimbing."
4
+ ---
5
+
6
+ # Coding-agent skills
7
+
8
+ Each skill is a procedure a coding agent can follow. Installing
9
+ `@cursor/july` copies them into `~/.cursor/skills/agentsdk/`. This site
10
+ publishes the same files.
11
+
12
+ See [Building agents with agents](../building-with-agents.md) for when
13
+ to use each one.
14
+
15
+ | Skill | Use it to |
16
+ | --- | --- |
17
+ | [framework-map](./framework-map.md) | Learn the project layout and runtimes |
18
+ | [create-agent](./create-agent.md) | Scaffold and verify a new agent |
19
+ | [evals](./evals.md) | Write fixtures and regression checks |
20
+ | [ab](./ab.md) | Compare variants on live traffic |
21
+ | [otel](./otel.md) | Export OpenTelemetry traces |
22
+ | [hillclimb](./hillclimb.md) | Improve an agent against fixed inputs |
23
+ | [github](./github.md) | Add GitHub webhooks and replay events |
24
+ | [setup-slack](./setup-slack.md) | Connect an agent to Slack |
25
+ | [mcp-auth](./mcp-auth.md) | Authorize host MCP OAuth |
26
+ | [debug](./debug.md) | Diagnose a local run |
@@ -74,7 +74,7 @@ not on `PATH`, use `npx @cursor/july`.
74
74
  | Model asks for `mcp_auth` or IDE MCP for a connector it already has | Attached MCP is behind meta-tools. Set `advertiseTools: true` for named tools on local turns, or call it from a host tool via `ctx.host.mcp`. |
75
75
 
76
76
  See [Host MCP OAuth](./guides/mcp-oauth.md) and
77
- [`skills/mcp-auth/SKILL.md`](../skills/mcp-auth/SKILL.md).
77
+ [`skills/mcp-auth/SKILL.md`](./skills/mcp-auth.md).
78
78
 
79
79
  ## What if a secret showed up in a terminal transcript?
80
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor/july",
3
- "version": "0.1.99",
3
+ "version": "0.1.101",
4
4
  "description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {
@@ -95,6 +95,20 @@
95
95
  "import": "./dist/skills.js",
96
96
  "default": "./dist/skills.js"
97
97
  },
98
+ "./extensions": {
99
+ "anysphere-source": "./src/extensions.ts",
100
+ "bun": "./dist/extensions.js",
101
+ "types": "./dist/extensions.d.ts",
102
+ "import": "./dist/extensions.js",
103
+ "default": "./dist/extensions.js"
104
+ },
105
+ "./extensions/cursor-cloud-agents": {
106
+ "anysphere-source": "./src/extensions/cursor-cloud-agents/extension.ts",
107
+ "bun": "./dist/extensions/cursor-cloud-agents/extension.js",
108
+ "types": "./dist/extensions/cursor-cloud-agents/extension.d.ts",
109
+ "import": "./dist/extensions/cursor-cloud-agents/extension.js",
110
+ "default": "./dist/extensions/cursor-cloud-agents/extension.js"
111
+ },
98
112
  "./schedules": {
99
113
  "anysphere-source": "./src/schedules.ts",
100
114
  "types": "./dist/schedules.d.ts",
@@ -215,7 +229,7 @@
215
229
  }
216
230
  },
217
231
  "scripts": {
218
- "build": "tsgo -p tsconfig.build.json && node scripts/bundle-publish-shims.mjs && pnpm run build:playground && pnpm run docs:build",
232
+ "build": "tsgo -p tsconfig.build.json && node scripts/bundle-publish-shims.mjs && node scripts/copy-extension-assets.mjs && pnpm run build:playground && pnpm run docs:build",
219
233
  "build:dist": "node scripts/build-hosted-dist.mjs",
220
234
  "postinstall": "node -e \"try{const p='./scripts/install-cursor-skills.mjs';if(require('fs').existsSync(p))require('child_process').execFileSync(process.execPath,[p],{stdio:'inherit'})}catch{}\"",
221
235
  "build:playground": "vite build --config playground/vite.config.ts",
@@ -240,7 +254,7 @@
240
254
  },
241
255
  "dependencies": {
242
256
  "@bazel/runfiles": "6.5.0",
243
- "@cursor/sdk": "1.0.30",
257
+ "@cursor/sdk": "1.0.31",
244
258
  "@modelcontextprotocol/sdk": "1.25.1",
245
259
  "@octokit/auth-app": "^7.2.0",
246
260
  "@octokit/rest": "^21.1.1",
@@ -303,4 +317,4 @@
303
317
  "yaml": "^2.4.2",
304
318
  "zustand": "^5.0.9"
305
319
  }
306
- }
320
+ }
@@ -426,8 +426,8 @@ Options:
426
426
  --all deploy: every child agent under a multi-agent --dir
427
427
  (skips the interactive picker; mutually exclusive with
428
428
  --slug).
429
- --cursor-events-repo deploy: repo (owner/name) whose SCM events the
430
- deployed engine pulls (repeatable).
429
+ --cursor-events-repo deploy: repo (owner/name) the deployed agent
430
+ watches (repeatable).
431
431
  --allow-domain deploy: egress domain the engine pod may reach
432
432
  (repeatable; unioned with hosting.egressDomains from the
433
433
  agent manifest). Repo-backed deploys only.
@@ -1160,6 +1160,15 @@ async function main(argv: string[]): Promise<number> {
1160
1160
  info.skills.map((s) => `${s.name} — ${s.description}`)
1161
1161
  )
1162
1162
  );
1163
+ lines.push(
1164
+ section(
1165
+ "extensions",
1166
+ info.extensions.map(
1167
+ (e) =>
1168
+ `${e.name} — ${[...e.tools, ...e.skills].join(", ") || "(nothing contributed)"}`
1169
+ )
1170
+ )
1171
+ );
1163
1172
  lines.push(
1164
1173
  section(
1165
1174
  "MCP connections",
@@ -1,7 +1,11 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { defineChannel, localDevStrict, POST } from "../../channels.js";
4
- import { resolveDeploymentSubscriptions } from "../../internal/cursor-deployment-relay.js";
4
+ import {
5
+ deploymentEventMatches,
6
+ resolveDeploymentSubscriptions,
7
+ } from "../../internal/cursor-deployment-relay.js";
8
+ import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-adapter.js";
5
9
  import { bindLocalIngressSend } from "../../internal/local-ingress.js";
6
10
  import type { ChannelDefinition, ChannelHandlerArgs } from "../../types.js";
7
11
  import {
@@ -43,14 +47,28 @@ export function getDeploymentsChannelOptions(
43
47
  /**
44
48
  * Events a {@link deploymentsChannel} dispatches on, unioned from its
45
49
  * subscriptions. Published as `meta.deploymentEventTypes` so the deploy
46
- * manifest can extract `eventTypes`. An empty deploy-source list is an
47
- * inert channel and yields no events.
50
+ * manifest can extract `eventTypes`.
51
+ *
52
+ * A channel with no resolved subscriptions declares the full event set:
53
+ * deploy sources usually come from env vars read at module load, and the
54
+ * hosted freeze bakes hermetically (no customer env/secrets), so deriving
55
+ * `[]` there would leave the manifest without event types and no
56
+ * subscription edge could ever materialize (invariant 26). Capability is
57
+ * the channel's code shape — `onEvent` handles any deployment event —
58
+ * while sources/environments/event narrowing are runtime subscription
59
+ * config; the hosted-admission adapter re-applies them before authored
60
+ * code runs. Inertness is still guaranteed by scope: a deploy that names
61
+ * no deploy sources binds no edges.
48
62
  */
49
63
  export function deriveDeploymentEventTypes(
50
64
  options: Pick<DeploymentsChannelOptions, "deploySourceUris" | "events">
51
65
  ): string[] {
66
+ const subscriptions = resolveDeploymentSubscriptions(options);
67
+ if (subscriptions.length === 0) {
68
+ return [...DEPLOYMENT_EVENT_TYPES].sort();
69
+ }
52
70
  const events = new Set<string>();
53
- for (const subscription of resolveDeploymentSubscriptions(options)) {
71
+ for (const subscription of subscriptions) {
54
72
  for (const event of subscription.events) {
55
73
  events.add(event);
56
74
  }
@@ -59,9 +77,9 @@ export function deriveDeploymentEventTypes(
59
77
  }
60
78
 
61
79
  /**
62
- * Core deployment-event dispatch, used by the channel's replay route and by
63
- * the serve host's relay fan-out. Whether the event matches this channel's
64
- * subscriptions is the caller's decision.
80
+ * Core deployment-event dispatch, used by the channel's replay route, the
81
+ * serve host's relay fan-out, and the hosted-admission adapter. Whether the
82
+ * event matches this channel's subscriptions is the caller's decision.
65
83
  */
66
84
  export async function dispatchDeploymentEvent(input: {
67
85
  options: DeploymentsChannelOptions;
@@ -77,7 +95,61 @@ export async function dispatchDeploymentEvent(input: {
77
95
  payload: input.event,
78
96
  })
79
97
  );
80
- return Response.json({ ok: true });
98
+ // "task": authored `onEvent` ran to completion without a captured send.
99
+ // Hosted admission only consults this when no send was captured.
100
+ return withDispatchOutcome(Response.json({ ok: true }), "task");
101
+ }
102
+
103
+ export type DeploymentsDispatchOutcome = "skip" | "task";
104
+
105
+ const dispatchOutcomeByResponse = new WeakMap<
106
+ Response,
107
+ DeploymentsDispatchOutcome
108
+ >();
109
+
110
+ function withDispatchOutcome(
111
+ response: Response,
112
+ outcome: DeploymentsDispatchOutcome
113
+ ): Response {
114
+ dispatchOutcomeByResponse.set(response, outcome);
115
+ return response;
116
+ }
117
+
118
+ export function getDeploymentsDispatchOutcome(
119
+ response: Response
120
+ ): DeploymentsDispatchOutcome | undefined {
121
+ return dispatchOutcomeByResponse.get(response);
122
+ }
123
+
124
+ /**
125
+ * Whether this channel admits the event on a hosted pod. The hosted
126
+ * control plane fans out on `(deploy_source, eventType, team)` edges only —
127
+ * environments are not edge identity — so this is where the environment
128
+ * filter (and a stale-edge guard for sources/events) lives, mirroring what
129
+ * the v1 relay does before `onEvent`.
130
+ *
131
+ * A channel with NO resolved subscriptions admits everything the control
132
+ * plane delivered: deploy sources usually come from env vars read at
133
+ * module load, and the hosted freeze bakes hermetically (no customer env),
134
+ * so on a restored pod an env-configured channel resolves empty — the
135
+ * deploy-time edges (bound from the watched repositories) already carry
136
+ * the customer's scope, and refusing here would silently drop every
137
+ * delivery. Same posture as {@link deriveDeploymentEventTypes}: authored
138
+ * subscriptions narrow; an unconfigured channel defers to the deploy scope.
139
+ */
140
+ export function deploymentEventMatchesChannel(
141
+ options: DeploymentsChannelOptions,
142
+ event: DeploymentEvent
143
+ ): boolean {
144
+ const subscriptions = resolveDeploymentSubscriptions(options);
145
+ if (subscriptions.length === 0) {
146
+ return true;
147
+ }
148
+ return subscriptions.some(
149
+ (subscription) =>
150
+ subscription.deploySourceUri === event.deploySourceUri.toLowerCase() &&
151
+ deploymentEventMatches(subscription, event)
152
+ );
81
153
  }
82
154
 
83
155
  /**
@@ -102,6 +174,13 @@ export async function dispatchDeploymentEvent(input: {
102
174
  * have. Nothing is pushed to this deployment and no shared secret exists on
103
175
  * either side.
104
176
  *
177
+ * Hosted v2 deployments do not poll: the control plane fans verified factory
178
+ * deployment events out on `deploy_source` subscription edges — derived from
179
+ * the deploy's watched `repositories`, since factory records deploy sources
180
+ * as Origin repo URLs — and delivers through hosted admission. The attached
181
+ * adapter re-applies this channel's subscription filter — environments are
182
+ * not edge identity — and skips before authored code runs.
183
+ *
105
184
  * The route on this channel exists for local replay (`agent-sdk` and tests):
106
185
  * POST an event body and it runs the same `onEvent`.
107
186
  */
@@ -136,5 +215,35 @@ export function deploymentsChannel(
136
215
  ],
137
216
  });
138
217
  deploymentsChannelOptionsByDefinition.set(definition, options);
218
+ // Hosted v2 delivery: the control plane admits a deployments mailbox item
219
+ // (deploy_source edge match) and posts the claim-checked factory envelope
220
+ // here. Environments are not edge identity, so non-matching environments
221
+ // (and stale-edge sources/events) are filtered to `skip` before authored
222
+ // code runs — the same pre-`onEvent` filter the v1 relay applies.
223
+ attachHostedAdmissionAdapter(definition, {
224
+ kind: DEPLOYMENTS_CHANNEL_KIND,
225
+ dispatch: async ({ payload, args }) => {
226
+ const parsed = deploymentEventSchema.safeParse(payload);
227
+ if (!parsed.success) {
228
+ return Response.json(
229
+ { ok: false, error: "invalid_deployment_event" },
230
+ { status: 400 }
231
+ );
232
+ }
233
+ const event = parsed.data as DeploymentEvent;
234
+ if (!deploymentEventMatchesChannel(options, event)) {
235
+ return withDispatchOutcome(
236
+ Response.json({
237
+ ok: true,
238
+ skipped: true,
239
+ reason: "subscription_mismatch",
240
+ }),
241
+ "skip"
242
+ );
243
+ }
244
+ return dispatchDeploymentEvent({ options, event, args });
245
+ },
246
+ getOutcome: (response) => getDeploymentsDispatchOutcome(response),
247
+ });
139
248
  return definition;
140
249
  }
@@ -54,9 +54,10 @@ export interface DeploymentsChannelOptions {
54
54
  * and then receives nothing. A bare string takes the default environment and
55
55
  * event filters.
56
56
  *
57
- * There is no team-wide subscription: every deploy source is named. At least
58
- * one is required — an empty list is how a consumer *deregisters*, so it
59
- * cannot also mean "everything".
57
+ * There is no team-wide subscription: every deploy source is named. An
58
+ * empty list is how a consumer *deregisters*, so it cannot also mean
59
+ * "everything". A live array that starts empty and is filled later is
60
+ * re-read on each registration heartbeat.
60
61
  */
61
62
  deploySourceUris: readonly (string | DeploymentSubscription)[];
62
63
  /**
@@ -27,9 +27,18 @@ export function buildDefaultGitHubEvents(
27
27
  options: BuildDefaultGitHubEventsOptions = {}
28
28
  ): ChannelEventHandlers<GitHubChannelState> {
29
29
  const deliverReplies = options.deliverReplies !== false;
30
+ const requiredSuccessfulTools = new Set(
31
+ options.progress?.requireSuccessfulTools
32
+ ?.map((toolName) => toolName.trim())
33
+ .filter((toolName) => toolName !== "") ?? []
34
+ );
35
+ const toolOutcomesBySession = new Map<string, Map<string, boolean>>();
30
36
 
31
37
  return {
32
- async "turn.started"(_event, channel) {
38
+ async "turn.started"(event, channel) {
39
+ if (requiredSuccessfulTools.size > 0) {
40
+ toolOutcomesBySession.set(event.sessionId, new Map());
41
+ }
33
42
  await applyGitHubProgress({
34
43
  phase: "pending",
35
44
  channel,
@@ -52,9 +61,31 @@ export function buildDefaultGitHubEvents(
52
61
  }
53
62
  },
54
63
 
55
- async "turn.completed"(_event, channel) {
64
+ async "action.result"(event) {
65
+ if (
66
+ event.data.parentCallId !== undefined ||
67
+ !requiredSuccessfulTools.has(event.data.toolName)
68
+ ) {
69
+ return;
70
+ }
71
+ const outcomes = toolOutcomesBySession.get(event.sessionId) ?? new Map();
72
+ outcomes.set(
73
+ event.data.toolName,
74
+ !event.data.isError && event.data.stubbed !== true
75
+ );
76
+ toolOutcomesBySession.set(event.sessionId, outcomes);
77
+ },
78
+
79
+ async "turn.completed"(event, channel) {
80
+ const outcomes = toolOutcomesBySession.get(event.sessionId);
81
+ const pipelineSucceeded =
82
+ requiredSuccessfulTools.size === 0 ||
83
+ [...requiredSuccessfulTools].every(
84
+ (toolName) => outcomes?.get(toolName) === true
85
+ );
86
+ toolOutcomesBySession.delete(event.sessionId);
56
87
  await applyGitHubProgress({
57
- phase: "success",
88
+ phase: pipelineSucceeded ? "success" : "failure",
58
89
  channel,
59
90
  options,
60
91
  });
@@ -82,6 +113,7 @@ export function buildDefaultGitHubEvents(
82
113
  },
83
114
 
84
115
  async "turn.failed"(event, channel) {
116
+ toolOutcomesBySession.delete(event.sessionId);
85
117
  await applyGitHubProgress({
86
118
  phase: "failure",
87
119
  channel,
@@ -91,6 +123,7 @@ export function buildDefaultGitHubEvents(
91
123
  },
92
124
 
93
125
  async "session.failed"(event, channel) {
126
+ toolOutcomesBySession.delete(event.sessionId);
94
127
  await applyGitHubProgress({
95
128
  phase: "failure",
96
129
  channel,
@@ -35,6 +35,13 @@ export type GitHubBannerProgress = GitHubProgressPhaseCopy;
35
35
  export interface GitHubProgressConfig {
36
36
  /** When false, skip the eyes reaction on turn.started. Defaults to true. */
37
37
  reactions?: boolean;
38
+ /**
39
+ * Top-level tools that must each finish successfully before a completed
40
+ * turn is reported as successful. A missing, stubbed, or ultimately failed
41
+ * tool reports failure instead. Later successful retries replace an earlier
42
+ * failure for the same tool.
43
+ */
44
+ requireSuccessfulTools?: readonly string[];
38
45
  /**
39
46
  * Opt-in Checks API run on the PR head. Omit or `false` keeps today's
40
47
  * behavior (no check from default events). With `cursorAccount`, enabling