@cursor/july 0.1.93 → 0.1.95

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 (440) hide show
  1. package/AGENTS.md +8 -20
  2. package/README.md +4 -26
  3. package/dist/channels/github/github-channel.d.ts.map +1 -1
  4. package/dist/channels/github/github-channel.js +14 -2
  5. package/dist/channels/github/types.d.ts +18 -3
  6. package/dist/channels/github/types.d.ts.map +1 -1
  7. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  8. package/dist/channels/origin/origin-channel.js +11 -3
  9. package/dist/channels/origin/origin-webhook.d.ts +11 -1
  10. package/dist/channels/origin/origin-webhook.d.ts.map +1 -1
  11. package/dist/channels/origin/origin-webhook.js +23 -3
  12. package/dist/channels/origin/types.d.ts +8 -0
  13. package/dist/channels/origin/types.d.ts.map +1 -1
  14. package/dist/channels/slack/attachments.js +2 -2
  15. package/dist/channels/slack/dispatch.d.ts +0 -7
  16. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  17. package/dist/channels/slack/dispatch.js +4 -7
  18. package/dist/channels/slack/eval-directive.d.ts +5 -12
  19. package/dist/channels/slack/eval-directive.d.ts.map +1 -1
  20. package/dist/channels/slack/eval-directive.js +8 -19
  21. package/dist/channels/slack/index.d.ts +0 -6
  22. package/dist/channels/slack/index.d.ts.map +1 -1
  23. package/dist/channels/slack/index.js +0 -6
  24. package/dist/channels/slack/pr-ref.d.ts +7 -1
  25. package/dist/channels/slack/pr-ref.d.ts.map +1 -1
  26. package/dist/channels/slack/pr-ref.js +42 -23
  27. package/dist/channels/slack/setup.d.ts +4 -4
  28. package/dist/channels/slack/setup.d.ts.map +1 -1
  29. package/dist/channels/slack/setup.js +8 -15
  30. package/dist/channels/slack/slack-channel.d.ts +6 -13
  31. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  32. package/dist/channels/slack/slack-channel.js +15 -101
  33. package/dist/channels/slack/types.d.ts +12 -79
  34. package/dist/channels/slack/types.d.ts.map +1 -1
  35. package/dist/channels/slack/types.js +1 -15
  36. package/dist/client.d.ts +14 -0
  37. package/dist/client.d.ts.map +1 -0
  38. package/dist/client.js +12 -0
  39. package/dist/connections.d.ts +18 -9
  40. package/dist/connections.d.ts.map +1 -1
  41. package/dist/connections.js +17 -8
  42. package/dist/docs/404.html +2 -2
  43. package/dist/docs/ab.html +4 -4
  44. package/dist/docs/assets/{app.CjWU-x0z.js → app.BBj0klBO.js} +1 -1
  45. package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +1 -0
  46. package/dist/docs/assets/chunks/{VPLocalSearchBox.Cxy8ySFQ.js → VPLocalSearchBox.CUEXpL78.js} +1 -1
  47. package/dist/docs/assets/chunks/{theme.Dvq1Bktu.js → theme.DabmQnia.js} +2 -2
  48. package/dist/docs/assets/concepts.md.lwAgBIMI.js +1 -0
  49. package/dist/docs/assets/{deployment.md.DoLFAzfm.js → deployment.md.D9msOFOW.js} +3 -8
  50. package/dist/docs/assets/{deployment.md.DoLFAzfm.lean.js → deployment.md.D9msOFOW.lean.js} +1 -1
  51. package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.js → guides_agent-to-agent.md.BDb0t1QV.js} +1 -1
  52. package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.js +9 -0
  53. package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.lean.js +1 -0
  54. package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.js → guides_convert-automation.md.B4sjlodG.js} +1 -1
  55. package/dist/docs/assets/{guides_github.md.DqJhuaN1.js → guides_github.md.Cnh2mL4a.js} +1 -1
  56. package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.js → guides_mcp-oauth.md.DPYmBCbV.js} +7 -9
  57. package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.lean.js → guides_mcp-oauth.md.DPYmBCbV.lean.js} +1 -1
  58. package/dist/docs/assets/{guides_slack.md.mqeNKs84.js → guides_slack.md.C32HsdKk.js} +5 -11
  59. package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +1 -0
  60. package/dist/docs/assets/index.md.BoHaMdeZ.js +5 -0
  61. package/dist/docs/assets/{index.md.B-lVR4wT.lean.js → index.md.BoHaMdeZ.lean.js} +1 -1
  62. package/dist/docs/assets/{quickstart.md.BrmfrrIr.js → quickstart.md.Nj_LjW_a.js} +1 -1
  63. package/dist/docs/assets/{reference_cli.md.D9KESDsD.js → reference_cli.md.BsMOxDvh.js} +4 -3
  64. package/dist/docs/assets/{reference_cli.md.D9KESDsD.lean.js → reference_cli.md.BsMOxDvh.lean.js} +1 -1
  65. package/dist/docs/assets/{reference_connections.md.DB6SsN6U.js → reference_connections.md.BH8Oc0D0.js} +5 -5
  66. package/dist/docs/assets/{reference_connections.md.DB6SsN6U.lean.js → reference_connections.md.BH8Oc0D0.lean.js} +1 -1
  67. package/dist/docs/assets/{reference_hooks.md.BxN87gCw.js → reference_hooks.md.a8BJxMR5.js} +1 -1
  68. package/dist/docs/assets/reference_http-api.md.D89k1mdm.js +11 -0
  69. package/dist/docs/assets/reference_http-api.md.D89k1mdm.lean.js +1 -0
  70. package/dist/docs/assets/reference_project-layout.md.Bv4KOtlB.js +19 -0
  71. package/dist/docs/assets/{reference_subagents.md.Xoav0AII.js → reference_subagents.md.CfsIloPm.js} +1 -1
  72. package/dist/docs/assets/{reference_tools.md.DuKvkYWG.js → reference_tools.md.BHeXn2id.js} +3 -3
  73. package/dist/docs/assets/{reference_tools.md.DuKvkYWG.lean.js → reference_tools.md.BHeXn2id.lean.js} +1 -1
  74. package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.js → templates_agentic-owners.md.BZSH4N9z.js} +1 -1
  75. package/dist/docs/assets/{templates_demo.md.DhFcWN6j.js → templates_demo.md.BeQX9V3H.js} +1 -1
  76. package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.js → templates_pr-autofixer.md.x5zl6-GT.js} +2 -2
  77. package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.lean.js → templates_pr-autofixer.md.x5zl6-GT.lean.js} +1 -1
  78. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +4 -0
  79. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +1 -0
  80. package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.js → templates_security-reviewer.md.lshxbCLK.js} +2 -2
  81. package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.lean.js → templates_security-reviewer.md.lshxbCLK.lean.js} +1 -1
  82. package/dist/docs/assets/{templates_triage.md.CVlpctKS.js → templates_triage.md.Co4UNzkZ.js} +3 -3
  83. package/dist/docs/assets/{templates_triage.md.CVlpctKS.lean.js → templates_triage.md.Co4UNzkZ.lean.js} +1 -1
  84. package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +1 -0
  85. package/dist/docs/building-with-agents.html +4 -4
  86. package/dist/docs/concepts.html +5 -5
  87. package/dist/docs/concepts.md +1 -0
  88. package/dist/docs/deployment.html +7 -12
  89. package/dist/docs/deployment.md +1 -20
  90. package/dist/docs/design/agsh.md +406 -0
  91. package/dist/docs/evals.html +4 -4
  92. package/dist/docs/guides/agent-to-agent.html +6 -6
  93. package/dist/docs/guides/agent-to-agent.md +2 -2
  94. package/dist/docs/guides/cloud-runtime.html +6 -6
  95. package/dist/docs/guides/cloud-runtime.md +1 -0
  96. package/dist/docs/guides/convert-automation.html +6 -6
  97. package/dist/docs/guides/convert-automation.md +1 -1
  98. package/dist/docs/guides/github.html +6 -6
  99. package/dist/docs/guides/github.md +4 -4
  100. package/dist/docs/guides/human-in-the-loop.html +4 -4
  101. package/dist/docs/guides/mcp-oauth.html +11 -13
  102. package/dist/docs/guides/mcp-oauth.md +10 -18
  103. package/dist/docs/guides/opentelemetry.html +5 -5
  104. package/dist/docs/guides/slack.html +9 -15
  105. package/dist/docs/guides/slack.md +9 -46
  106. package/dist/docs/guides/webhooks.html +4 -4
  107. package/dist/docs/hashmap.json +1 -1
  108. package/dist/docs/hillclimbing.html +4 -4
  109. package/dist/docs/index.html +6 -6
  110. package/dist/docs/index.md +3 -29
  111. package/dist/docs/llms-full.txt +756 -2810
  112. package/dist/docs/llms.txt +3 -16
  113. package/dist/docs/quickstart.html +6 -6
  114. package/dist/docs/quickstart.md +2 -3
  115. package/dist/docs/reference/agent-config.html +4 -4
  116. package/dist/docs/reference/artifacts.html +4 -4
  117. package/dist/docs/reference/channels.html +4 -4
  118. package/dist/docs/reference/cli.html +8 -7
  119. package/dist/docs/reference/cli.md +5 -2
  120. package/dist/docs/reference/connections.html +9 -9
  121. package/dist/docs/reference/connections.md +15 -11
  122. package/dist/docs/reference/hooks.html +6 -6
  123. package/dist/docs/reference/hooks.md +2 -3
  124. package/dist/docs/reference/http-api.html +6 -6
  125. package/dist/docs/reference/http-api.md +8 -0
  126. package/dist/docs/reference/instructions.html +4 -4
  127. package/dist/docs/reference/playground.html +4 -4
  128. package/dist/docs/reference/project-layout.html +8 -6
  129. package/dist/docs/reference/project-layout.md +5 -1
  130. package/dist/docs/reference/prompt.html +4 -4
  131. package/dist/docs/reference/schedules.html +4 -4
  132. package/dist/docs/reference/sessions.html +4 -4
  133. package/dist/docs/reference/skills.html +4 -4
  134. package/dist/docs/reference/subagents.html +6 -6
  135. package/dist/docs/reference/subagents.md +2 -2
  136. package/dist/docs/reference/tools.html +7 -7
  137. package/dist/docs/reference/tools.md +19 -3
  138. package/dist/docs/scaffolding-agents.html +4 -4
  139. package/dist/docs/storage.html +4 -4
  140. package/dist/docs/templates/agentic-owners.html +7 -7
  141. package/dist/docs/templates/agentic-owners.md +1 -1
  142. package/dist/docs/templates/demo.html +6 -6
  143. package/dist/docs/templates/demo.md +3 -2
  144. package/dist/docs/templates/pr-autofixer.html +6 -6
  145. package/dist/docs/templates/pr-autofixer.md +8 -13
  146. package/dist/docs/templates/security-help.html +30 -0
  147. package/dist/docs/templates/security-help.md +65 -0
  148. package/dist/docs/templates/security-reviewer.html +6 -6
  149. package/dist/docs/templates/security-reviewer.md +1 -3
  150. package/dist/docs/templates/triage.html +7 -7
  151. package/dist/docs/templates/triage.md +2 -6
  152. package/dist/docs/troubleshooting.html +5 -5
  153. package/dist/docs/troubleshooting.md +2 -2
  154. package/dist/files-backends/cursor-hosted.d.ts +6 -2
  155. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  156. package/dist/files-backends/cursor-hosted.js +2 -2
  157. package/dist/files.d.ts +2 -0
  158. package/dist/files.d.ts.map +1 -1
  159. package/dist/files.js +5 -0
  160. package/dist/index.d.ts +1 -1
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +1 -1
  163. package/dist/internal/advertise-tools.d.ts +11 -0
  164. package/dist/internal/advertise-tools.d.ts.map +1 -1
  165. package/dist/internal/advertise-tools.js +47 -9
  166. package/dist/internal/cli-deploy.d.ts.map +1 -1
  167. package/dist/internal/cli-deploy.js +135 -6
  168. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  169. package/dist/internal/cli-mcp-oauth.js +7 -4
  170. package/dist/internal/conversation-mirror.d.ts +82 -0
  171. package/dist/internal/conversation-mirror.d.ts.map +1 -0
  172. package/dist/internal/conversation-mirror.js +251 -0
  173. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
  174. package/dist/internal/convert-automation/convert-workflow.js +26 -15
  175. package/dist/internal/convert-automation/slug.d.ts +0 -2
  176. package/dist/internal/convert-automation/slug.d.ts.map +1 -1
  177. package/dist/internal/convert-automation/slug.js +0 -8
  178. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  179. package/dist/internal/cursor/account-mcp.js +5 -1
  180. package/dist/internal/deferred-channel-session.d.ts +20 -0
  181. package/dist/internal/deferred-channel-session.d.ts.map +1 -0
  182. package/dist/internal/deferred-channel-session.js +62 -0
  183. package/dist/internal/deploy-client.d.ts +13 -1
  184. package/dist/internal/deploy-client.d.ts.map +1 -1
  185. package/dist/internal/deploy-client.js +11 -1
  186. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  187. package/dist/internal/deploy-manifest.js +11 -5
  188. package/dist/internal/discovery.d.ts.map +1 -1
  189. package/dist/internal/discovery.js +110 -15
  190. package/dist/internal/framework-storage-selection.d.ts +32 -16
  191. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  192. package/dist/internal/framework-storage-selection.js +51 -17
  193. package/dist/internal/hosted-admission-context.d.ts +20 -0
  194. package/dist/internal/hosted-admission-context.d.ts.map +1 -0
  195. package/dist/internal/hosted-admission-context.js +31 -0
  196. package/dist/internal/hosted-delivery-protocol.d.ts +5 -0
  197. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  198. package/dist/internal/hosted-delivery-protocol.js +33 -1
  199. package/dist/internal/hosted-delivery.d.ts +4 -2
  200. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  201. package/dist/internal/hosted-delivery.js +97 -44
  202. package/dist/internal/hosted-managed-automation.d.ts +30 -0
  203. package/dist/internal/hosted-managed-automation.d.ts.map +1 -0
  204. package/dist/internal/hosted-managed-automation.js +58 -0
  205. package/dist/internal/mcp-endpoint.js +3 -3
  206. package/dist/internal/mcp-host.d.ts +8 -7
  207. package/dist/internal/mcp-host.d.ts.map +1 -1
  208. package/dist/internal/mcp-host.js +8 -7
  209. package/dist/internal/peer-connections.d.ts.map +1 -1
  210. package/dist/internal/peer-connections.js +5 -1
  211. package/dist/internal/playground/static.d.ts +0 -3
  212. package/dist/internal/playground/static.d.ts.map +1 -1
  213. package/dist/internal/resolved-connections.d.ts.map +1 -1
  214. package/dist/internal/resolved-connections.js +5 -7
  215. package/dist/internal/review-comments.d.ts.map +1 -1
  216. package/dist/internal/review-comments.js +10 -98
  217. package/dist/internal/scm/pr-url.d.ts +14 -0
  218. package/dist/internal/scm/pr-url.d.ts.map +1 -0
  219. package/dist/internal/scm/pr-url.js +65 -0
  220. package/dist/internal/sdk-runner.d.ts +14 -0
  221. package/dist/internal/sdk-runner.d.ts.map +1 -1
  222. package/dist/internal/sdk-runner.js +41 -2
  223. package/dist/internal/server.d.ts.map +1 -1
  224. package/dist/internal/server.js +123 -174
  225. package/dist/internal/session-engine.d.ts +45 -10
  226. package/dist/internal/session-engine.d.ts.map +1 -1
  227. package/dist/internal/session-engine.js +217 -65
  228. package/dist/internal/tool-catalog.d.ts +31 -0
  229. package/dist/internal/tool-catalog.d.ts.map +1 -0
  230. package/dist/internal/tool-catalog.js +67 -0
  231. package/dist/playground/assets/index-CF7hUDnQ.css +1 -0
  232. package/dist/playground/assets/{index-D9MFzhNE.js → index-CZA1uEWA.js} +48 -48
  233. package/dist/playground/index.html +2 -2
  234. package/dist/storage-backends/cursor-hosted.d.ts +7 -2
  235. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  236. package/dist/storage-backends/cursor-hosted.js +2 -2
  237. package/dist/types.d.ts +72 -23
  238. package/dist/types.d.ts.map +1 -1
  239. package/dist/types.js +19 -0
  240. package/docs/README.md +3 -29
  241. package/docs/concepts.md +1 -0
  242. package/docs/deployment.md +1 -20
  243. package/docs/design/agsh.md +406 -0
  244. package/docs/guides/agent-to-agent.md +2 -2
  245. package/docs/guides/cloud-runtime.md +1 -0
  246. package/docs/guides/convert-automation.md +1 -1
  247. package/docs/guides/github.md +4 -4
  248. package/docs/guides/mcp-oauth.md +10 -18
  249. package/docs/guides/slack.md +10 -47
  250. package/docs/quickstart.md +2 -3
  251. package/docs/reference/cli.md +5 -2
  252. package/docs/reference/connections.md +15 -11
  253. package/docs/reference/hooks.md +2 -3
  254. package/docs/reference/http-api.md +8 -0
  255. package/docs/reference/project-layout.md +5 -1
  256. package/docs/reference/subagents.md +2 -2
  257. package/docs/reference/tools.md +19 -3
  258. package/docs/templates/agentic-owners.md +1 -1
  259. package/docs/templates/demo.md +3 -2
  260. package/docs/templates/pr-autofixer.md +8 -13
  261. package/docs/templates/security-help.md +70 -0
  262. package/docs/templates/security-reviewer.md +1 -3
  263. package/docs/templates/triage.md +2 -6
  264. package/docs/troubleshooting.md +2 -2
  265. package/package.json +9 -2
  266. package/skills/create-agent/SKILL.md +6 -13
  267. package/skills/debug/SKILL.md +2 -4
  268. package/skills/evals/SKILL.md +1 -1
  269. package/skills/framework-map/SKILL.md +3 -2
  270. package/skills/mcp-auth/SKILL.md +10 -13
  271. package/skills/setup-slack/SKILL.md +21 -137
  272. package/src/channels/github/github-channel.ts +23 -8
  273. package/src/channels/github/types.ts +19 -2
  274. package/src/channels/origin/origin-channel.ts +13 -1
  275. package/src/channels/origin/origin-webhook.ts +27 -3
  276. package/src/channels/origin/types.ts +8 -0
  277. package/src/channels/slack/attachments.ts +2 -2
  278. package/src/channels/slack/dispatch.ts +2 -16
  279. package/src/channels/slack/eval-directive.ts +8 -27
  280. package/src/channels/slack/index.ts +0 -6
  281. package/src/channels/slack/pr-ref.ts +56 -25
  282. package/src/channels/slack/setup.ts +8 -15
  283. package/src/channels/slack/slack-channel.ts +14 -125
  284. package/src/channels/slack/types.ts +12 -96
  285. package/src/client.ts +23 -0
  286. package/src/connections.ts +20 -7
  287. package/src/files-backends/cursor-hosted.ts +9 -3
  288. package/src/files.ts +11 -0
  289. package/src/index.ts +2 -0
  290. package/src/internal/advertise-tools.ts +45 -7
  291. package/src/internal/cli-deploy.ts +171 -7
  292. package/src/internal/cli-mcp-oauth.ts +6 -4
  293. package/src/internal/conversation-mirror.ts +330 -0
  294. package/src/internal/convert-automation/convert-workflow.ts +29 -17
  295. package/src/internal/convert-automation/slug.ts +0 -9
  296. package/src/internal/cursor/account-mcp.ts +4 -1
  297. package/src/internal/deferred-channel-session.ts +61 -0
  298. package/src/internal/deploy-client.ts +24 -1
  299. package/src/internal/deploy-manifest.ts +10 -5
  300. package/src/internal/discovery.ts +129 -15
  301. package/src/internal/fixtures/units-server.ts +52 -0
  302. package/src/internal/framework-storage-selection.ts +61 -19
  303. package/src/internal/hosted-admission-context.ts +37 -0
  304. package/src/internal/hosted-delivery-protocol.ts +44 -1
  305. package/src/internal/hosted-delivery.ts +155 -68
  306. package/src/internal/hosted-managed-automation.ts +72 -0
  307. package/src/internal/mcp-endpoint.ts +3 -3
  308. package/src/internal/mcp-host.ts +8 -7
  309. package/src/internal/peer-connections.ts +4 -1
  310. package/src/internal/playground/static.ts +1 -3
  311. package/src/internal/resolved-connections.ts +8 -10
  312. package/src/internal/review-comments.ts +10 -113
  313. package/src/internal/scm/pr-url.ts +95 -0
  314. package/src/internal/sdk-runner.ts +57 -2
  315. package/src/internal/server.ts +161 -251
  316. package/src/internal/session-engine.ts +266 -69
  317. package/src/internal/tool-catalog.ts +106 -0
  318. package/src/storage-backends/cursor-hosted.ts +10 -3
  319. package/src/types.ts +90 -23
  320. package/templates/agentic-owners/README.md +1 -1
  321. package/templates/agentic-owners/agent/agent.ts +0 -10
  322. package/templates/agentic-owners/agent/channels/github.ts +5 -14
  323. package/templates/agentic-owners/agent/lib/config.ts +0 -8
  324. package/templates/agentic-owners/agent/lib/review.ts +2 -15
  325. package/templates/agentic-owners/agent/tools/record_review.ts +2 -4
  326. package/templates/demo/agent/agent.ts +0 -10
  327. package/templates/pr-autofixer/README.md +0 -2
  328. package/templates/pr-autofixer/agent/agent.ts +0 -11
  329. package/templates/pr-autofixer/agent/channels/slack.ts +1 -2
  330. package/templates/pr-autofixer/agent/lib/pr-state.ts +5 -17
  331. package/templates/pr-autofixer/agent/lib/repos.ts +0 -1
  332. package/templates/security-help/README.md +2 -2
  333. package/templates/security-help/agent/agent.ts +1 -2
  334. package/templates/security-help/agent/channels/slack.ts +0 -3
  335. package/templates/security-help/agent/instructions.md +9 -10
  336. package/templates/security-help/agent/skills/access-request.md +1 -1
  337. package/templates/security-help/agent/skills/faq.md +31 -0
  338. package/templates/security-help/agent/skills/security-playbooks.md +1 -1
  339. package/templates/security-help/package.json +1 -2
  340. package/templates/security-reviewer/agent/agent.ts +0 -10
  341. package/templates/triage/README.md +2 -1
  342. package/templates/triage/agent/agent.ts +0 -10
  343. package/templates/triage/agent/channels/queue.ts +1 -1
  344. package/templates/triage/agent/channels/webhook.ts +1 -3
  345. package/templates/triage/overlays/jira/agent/mcp-connections/tracker.ts +0 -1
  346. package/templates/triage/overlays/linear/agent/mcp-connections/tracker.ts +0 -1
  347. package/dist/channels/slack/cursor-account.d.ts +0 -87
  348. package/dist/channels/slack/cursor-account.d.ts.map +0 -1
  349. package/dist/channels/slack/cursor-account.js +0 -100
  350. package/dist/docs/assets/chunks/@localSearchIndexroot.ChpIC3Zy.js +0 -1
  351. package/dist/docs/assets/concepts.md.F6AiPorA.js +0 -1
  352. package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.js +0 -10
  353. package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.lean.js +0 -1
  354. package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.js +0 -5
  355. package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.lean.js +0 -1
  356. package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.js +0 -11
  357. package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.lean.js +0 -1
  358. package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.js +0 -8
  359. package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.lean.js +0 -1
  360. package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.js +0 -8
  361. package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.lean.js +0 -1
  362. package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.js +0 -22
  363. package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.lean.js +0 -1
  364. package/dist/docs/assets/example-agents_index.md.ChBp0AX6.js +0 -2
  365. package/dist/docs/assets/example-agents_index.md.ChBp0AX6.lean.js +0 -1
  366. package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.js +0 -11
  367. package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.lean.js +0 -1
  368. package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.js +0 -10
  369. package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.lean.js +0 -1
  370. package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.js +0 -19
  371. package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.lean.js +0 -1
  372. package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.js +0 -5
  373. package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.lean.js +0 -1
  374. package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.js +0 -25
  375. package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.lean.js +0 -1
  376. package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.js +0 -9
  377. package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.lean.js +0 -1
  378. package/dist/docs/assets/guides_slack.md.mqeNKs84.lean.js +0 -1
  379. package/dist/docs/assets/index.md.B-lVR4wT.js +0 -5
  380. package/dist/docs/assets/reference_http-api.md.C68BERYr.js +0 -11
  381. package/dist/docs/assets/reference_http-api.md.C68BERYr.lean.js +0 -1
  382. package/dist/docs/assets/reference_project-layout.md.WN9nwJht.js +0 -17
  383. package/dist/docs/assets/troubleshooting.md.vCWwvqcJ.js +0 -1
  384. package/dist/docs/example-agents/approval-buddy.html +0 -36
  385. package/dist/docs/example-agents/approval-buddy.md +0 -266
  386. package/dist/docs/example-agents/benny.html +0 -31
  387. package/dist/docs/example-agents/benny.md +0 -173
  388. package/dist/docs/example-agents/bugbot.html +0 -37
  389. package/dist/docs/example-agents/bugbot.md +0 -229
  390. package/dist/docs/example-agents/codebase-wiki.html +0 -34
  391. package/dist/docs/example-agents/codebase-wiki.md +0 -167
  392. package/dist/docs/example-agents/codeowners-review.html +0 -34
  393. package/dist/docs/example-agents/codeowners-review.md +0 -192
  394. package/dist/docs/example-agents/concierge.html +0 -48
  395. package/dist/docs/example-agents/concierge.md +0 -200
  396. package/dist/docs/example-agents/index.html +0 -28
  397. package/dist/docs/example-agents/index.md +0 -99
  398. package/dist/docs/example-agents/knowledge-base.html +0 -37
  399. package/dist/docs/example-agents/knowledge-base.md +0 -168
  400. package/dist/docs/example-agents/oncall.html +0 -36
  401. package/dist/docs/example-agents/oncall.md +0 -212
  402. package/dist/docs/example-agents/security-reviewer.html +0 -45
  403. package/dist/docs/example-agents/security-reviewer.md +0 -265
  404. package/dist/docs/example-agents/slack-agent.html +0 -31
  405. package/dist/docs/example-agents/slack-agent.md +0 -142
  406. package/dist/docs/example-agents/weather-agent.html +0 -51
  407. package/dist/docs/example-agents/weather-agent.md +0 -297
  408. package/dist/internal/cursor-slack-relay.d.ts +0 -96
  409. package/dist/internal/cursor-slack-relay.d.ts.map +0 -1
  410. package/dist/internal/cursor-slack-relay.js +0 -176
  411. package/dist/playground/assets/index-D9N7-q97.css +0 -1
  412. package/docs/example-agents/approval-buddy.md +0 -271
  413. package/docs/example-agents/benny.md +0 -178
  414. package/docs/example-agents/bugbot.md +0 -234
  415. package/docs/example-agents/codebase-wiki.md +0 -172
  416. package/docs/example-agents/codeowners-review.md +0 -197
  417. package/docs/example-agents/concierge.md +0 -205
  418. package/docs/example-agents/index.md +0 -104
  419. package/docs/example-agents/knowledge-base.md +0 -173
  420. package/docs/example-agents/oncall.md +0 -217
  421. package/docs/example-agents/security-reviewer.md +0 -270
  422. package/docs/example-agents/slack-agent.md +0 -147
  423. package/docs/example-agents/weather-agent.md +0 -302
  424. package/src/channels/slack/cursor-account.ts +0 -202
  425. package/src/internal/cursor-slack-relay.ts +0 -249
  426. package/templates/security-help/agent/knowledge/faq/approvals.md +0 -5
  427. package/templates/security-help/agent/knowledge/faq/channels.md +0 -6
  428. package/templates/security-help/agent/knowledge/faq/phishing.md +0 -10
  429. package/templates/security-help/agent/skills/security-first-pass.md +0 -15
  430. /package/dist/docs/assets/{concepts.md.F6AiPorA.lean.js → concepts.md.lwAgBIMI.lean.js} +0 -0
  431. /package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.lean.js → guides_agent-to-agent.md.BDb0t1QV.lean.js} +0 -0
  432. /package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.lean.js → guides_convert-automation.md.B4sjlodG.lean.js} +0 -0
  433. /package/dist/docs/assets/{guides_github.md.DqJhuaN1.lean.js → guides_github.md.Cnh2mL4a.lean.js} +0 -0
  434. /package/dist/docs/assets/{quickstart.md.BrmfrrIr.lean.js → quickstart.md.Nj_LjW_a.lean.js} +0 -0
  435. /package/dist/docs/assets/{reference_hooks.md.BxN87gCw.lean.js → reference_hooks.md.a8BJxMR5.lean.js} +0 -0
  436. /package/dist/docs/assets/{reference_project-layout.md.WN9nwJht.lean.js → reference_project-layout.md.Bv4KOtlB.lean.js} +0 -0
  437. /package/dist/docs/assets/{reference_subagents.md.Xoav0AII.lean.js → reference_subagents.md.CfsIloPm.lean.js} +0 -0
  438. /package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.lean.js → templates_agentic-owners.md.BZSH4N9z.lean.js} +0 -0
  439. /package/dist/docs/assets/{templates_demo.md.DhFcWN6j.lean.js → templates_demo.md.BeQX9V3H.lean.js} +0 -0
  440. /package/dist/docs/assets/{troubleshooting.md.vCWwvqcJ.lean.js → troubleshooting.md.Ctv3T8C2.lean.js} +0 -0
@@ -10,6 +10,14 @@ import type {
10
10
  ChannelHandlerArgs,
11
11
  SendMessageOptions,
12
12
  } from "../types.js";
13
+ import {
14
+ createDeferredChannelSession,
15
+ DeferredChannelSessionError,
16
+ } from "./deferred-channel-session.js";
17
+ import {
18
+ HostedAdmissionLocalSendError,
19
+ runDuringHostedAdmission,
20
+ } from "./hosted-admission-context.js";
13
21
  import {
14
22
  HOSTED_ADMISSION_PATH,
15
23
  HOSTED_DELIVERY_HEADER,
@@ -19,6 +27,7 @@ import {
19
27
  parseHostedAdmission,
20
28
  parseHostedExecution,
21
29
  } from "./hosted-delivery-protocol.js";
30
+ import { recordHostedManagedAutomation } from "./hosted-managed-automation.js";
22
31
  import { errorResponse, readJsonObject } from "./http-channel.js";
23
32
  import type { Router } from "./router.js";
24
33
 
@@ -45,19 +54,66 @@ type ExecutionReply = {
45
54
  body: Record<string, unknown>;
46
55
  };
47
56
 
48
- class HostedSendAdmitted extends Error {
49
- constructor(
50
- readonly prompt: string,
51
- readonly options: SendMessageOptions
52
- ) {
53
- super("hosted channel admitted a send");
57
+ /**
58
+ * A second `send()` in one delivery is a deterministic authored bug — the
59
+ * wire protocol carries exactly one pending send per delivery — so it must
60
+ * fail the delivery exactly once. It surfaces as a 422 because the control
61
+ * plane retries 5xx admissions (fresh pod, side effects re-run, identical
62
+ * failure, up to the Temporal attempt cap); a non-5xx/408/429 status makes
63
+ * it reject the delivery non-retryably instead.
64
+ */
65
+ class HostedSendLimitExceeded extends Error {
66
+ constructor() {
67
+ super(
68
+ "The hosted delivery protocol carries exactly one pending send per " +
69
+ "delivery, and this delivery already captured one. Combine both " +
70
+ "messages into a single send(), or split the work across deliveries."
71
+ );
54
72
  }
55
73
  }
56
74
 
75
+ // Authored/task-derived text stays bounded on this internal response path
76
+ // (and is never persisted to Temporal history by the control plane).
77
+ const MAX_ERROR_MESSAGE_LENGTH = 1024;
78
+
79
+ function boundedMessage(text: string): string {
80
+ return text.length > MAX_ERROR_MESSAGE_LENGTH
81
+ ? `${text.slice(0, MAX_ERROR_MESSAGE_LENGTH)}…`
82
+ : text;
83
+ }
84
+
85
+ /**
86
+ * Classify deterministic authored protocol violations as non-retryable 422
87
+ * admissions. Anything else returns `undefined` so callers fall through to
88
+ * the existing (retryable or rethrow) handling.
89
+ */
90
+ function nonRetryableRejection(error: unknown): AdmissionDispatch | undefined {
91
+ const code =
92
+ error instanceof HostedSendLimitExceeded
93
+ ? "hosted_send_limit_exceeded"
94
+ : error instanceof DeferredChannelSessionError
95
+ ? "hosted_deferred_session_unusable"
96
+ : error instanceof HostedAdmissionLocalSendError
97
+ ? "hosted_local_send_rejected"
98
+ : undefined;
99
+ if (code === undefined) {
100
+ return undefined;
101
+ }
102
+ return {
103
+ response: errorResponse(
104
+ 422,
105
+ code,
106
+ boundedMessage((error as Error).message)
107
+ ),
108
+ };
109
+ }
110
+
57
111
  /**
58
112
  * Run authored admission without creating a framework session. V1 GitHub
59
- * `task` callbacks execute as sessionless work; `send` is captured and
60
- * resumed only after the control plane allocates `ses_…`.
113
+ * `task` callbacks execute as sessionless work; the first `send` is captured
114
+ * and executed only after the control plane allocates `ses_…`. Capturing
115
+ * does not terminate the caller — `send` returns an inert deferred handle so
116
+ * a task body runs to completion before the admission response is computed.
61
117
  */
62
118
  export async function dispatchHostedAdmission(
63
119
  input: DispatchInput
@@ -71,24 +127,28 @@ export async function dispatchHostedAdmission(
71
127
  ),
72
128
  };
73
129
  }
130
+ // The admission window marker follows the async graph into task bodies so
131
+ // the engine can refuse local sends that would bypass the capture stub.
132
+ return runDuringHostedAdmission(() => runAdmission(input, github));
133
+ }
74
134
 
135
+ async function runAdmission(
136
+ input: DispatchInput,
137
+ github: NonNullable<ReturnType<typeof getGitHubChannelOptions>>
138
+ ): Promise<AdmissionDispatch> {
75
139
  const background: Promise<unknown>[] = [];
76
- let deferredSend: HostedSendAdmitted | undefined;
140
+ let captured: { message: string; options: SendMessageOptions } | undefined;
77
141
  const args = withPropagatingGitHubBackgroundErrors({
78
142
  ...input.args,
79
143
  send: async (message, options = {}) => {
80
- throw new HostedSendAdmitted(message, options);
144
+ if (captured !== undefined) {
145
+ throw new HostedSendLimitExceeded();
146
+ }
147
+ captured = { message, options };
148
+ return createDeferredChannelSession();
81
149
  },
82
150
  waitUntil: (promise) => {
83
- background.push(
84
- promise.catch((error: unknown) => {
85
- if (error instanceof HostedSendAdmitted) {
86
- deferredSend = error;
87
- return;
88
- }
89
- throw error;
90
- })
91
- );
151
+ background.push(promise);
92
152
  },
93
153
  });
94
154
  let dispatched: Response;
@@ -101,20 +161,9 @@ export async function dispatchHostedAdmission(
101
161
  args,
102
162
  });
103
163
  } catch (error) {
104
- if (error instanceof HostedSendAdmitted) {
105
- return {
106
- response: Response.json({
107
- ok: true,
108
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
109
- outcome: "send",
110
- }),
111
- pendingSend: {
112
- channelId: input.delivery.channelId,
113
- message: error.prompt,
114
- options: error.options,
115
- mailboxContinuationKey: input.delivery.mailboxContinuationKey,
116
- },
117
- };
164
+ const rejected = nonRetryableRejection(error);
165
+ if (rejected !== undefined) {
166
+ return rejected;
118
167
  }
119
168
  throw error;
120
169
  }
@@ -129,15 +178,20 @@ export async function dispatchHostedAdmission(
129
178
 
130
179
  try {
131
180
  await Promise.all(background);
132
- } catch {
181
+ } catch (error) {
182
+ const rejected = nonRetryableRejection(error);
183
+ if (rejected !== undefined) {
184
+ return rejected;
185
+ }
133
186
  return {
134
- response: Response.json(
135
- { ok: false, error: "background_dispatch_failed" },
136
- { status: 503 }
187
+ response: errorResponse(
188
+ 503,
189
+ "background_dispatch_failed",
190
+ boundedMessage(error instanceof Error ? error.message : String(error))
137
191
  ),
138
192
  };
139
193
  }
140
- if (deferredSend !== undefined) {
194
+ if (captured !== undefined) {
141
195
  return {
142
196
  response: Response.json({
143
197
  ok: true,
@@ -146,8 +200,8 @@ export async function dispatchHostedAdmission(
146
200
  }),
147
201
  pendingSend: {
148
202
  channelId: input.delivery.channelId,
149
- message: deferredSend.prompt,
150
- options: deferredSend.options,
203
+ message: captured.message,
204
+ options: captured.options,
151
205
  mailboxContinuationKey: input.delivery.mailboxContinuationKey,
152
206
  },
153
207
  };
@@ -170,6 +224,19 @@ export async function dispatchHostedAdmission(
170
224
  };
171
225
  }
172
226
 
227
+ function withServerTiming(response: Response, durationMs: number): Response {
228
+ const headers = new Headers(response.headers);
229
+ headers.set(
230
+ "Server-Timing",
231
+ `agent_sdk;desc="hosted";dur=${Math.max(0, durationMs).toFixed(1)}`
232
+ );
233
+ return new Response(response.body, {
234
+ status: response.status,
235
+ statusText: response.statusText,
236
+ headers,
237
+ });
238
+ }
239
+
173
240
  export function registerHostedDeliveryRoute(input: {
174
241
  router: Router;
175
242
  base: string;
@@ -215,22 +282,30 @@ export function registerHostedDeliveryRoute(input: {
215
282
  pattern: `${input.base}${HOSTED_ADMISSION_PATH}`,
216
283
  auth: [auth],
217
284
  handler: async (request) => {
285
+ const startedAt = performance.now();
286
+ const finish = (response: Response) =>
287
+ withServerTiming(response, performance.now() - startedAt);
218
288
  const delivery = parseHostedAdmission(await readJsonObject(request));
219
289
  if (delivery === undefined) {
220
- return errorResponse(
221
- 400,
222
- "invalid_hosted_admission",
223
- "Expected a supported Agent SDK hosted-admission envelope."
290
+ return finish(
291
+ errorResponse(
292
+ 400,
293
+ "invalid_hosted_admission",
294
+ "Expected a supported Agent SDK hosted-admission envelope."
295
+ )
224
296
  );
225
297
  }
298
+ recordHostedManagedAutomation(delivery);
226
299
  const channel = input.channels.find(
227
300
  (candidate) => candidate.id === delivery.channelId
228
301
  );
229
302
  if (channel === undefined) {
230
- return errorResponse(
231
- 404,
232
- "channel_not_found",
233
- `No channel named "${delivery.channelId}" is mounted.`
303
+ return finish(
304
+ errorResponse(
305
+ 404,
306
+ "channel_not_found",
307
+ `No channel named "${delivery.channelId}" is mounted.`
308
+ )
234
309
  );
235
310
  }
236
311
  const admitted = await dispatchHostedAdmission({
@@ -239,7 +314,7 @@ export function registerHostedDeliveryRoute(input: {
239
314
  args: input.buildHandlerArgs(delivery.channelId),
240
315
  });
241
316
  if (admitted.pendingSend === undefined) {
242
- return admitted.response;
317
+ return finish(admitted.response);
243
318
  }
244
319
  pruneExpired();
245
320
  const admissionToken = randomBytes(24).toString("hex");
@@ -247,12 +322,14 @@ export function registerHostedDeliveryRoute(input: {
247
322
  send: admitted.pendingSend,
248
323
  expiresAt: Date.now() + pendingTtlMs,
249
324
  });
250
- return Response.json({
251
- ok: true,
252
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
253
- outcome: "send",
254
- admissionToken,
255
- });
325
+ return finish(
326
+ Response.json({
327
+ ok: true,
328
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
329
+ outcome: "send",
330
+ admissionToken,
331
+ })
332
+ );
256
333
  },
257
334
  });
258
335
  input.router.add({
@@ -260,31 +337,41 @@ export function registerHostedDeliveryRoute(input: {
260
337
  pattern: `${input.base}${HOSTED_EXECUTION_PATH}`,
261
338
  auth: [auth],
262
339
  handler: async (request) => {
340
+ const startedAt = performance.now();
341
+ const finish = (response: Response) =>
342
+ withServerTiming(response, performance.now() - startedAt);
343
+
263
344
  const execution = parseHostedExecution(await readJsonObject(request));
264
345
  if (execution === undefined) {
265
- return errorResponse(
266
- 400,
267
- "invalid_hosted_execution",
268
- "Expected a supported Agent SDK hosted-execution envelope."
346
+ return finish(
347
+ errorResponse(
348
+ 400,
349
+ "invalid_hosted_execution",
350
+ "Expected a supported Agent SDK hosted-execution envelope."
351
+ )
269
352
  );
270
353
  }
271
354
  pruneExpired();
272
355
  const admitted = pending.get(execution.admissionToken);
273
356
  if (admitted === undefined) {
274
- return errorResponse(
275
- 409,
276
- "hosted_admission_unavailable",
277
- "The hosted admission token is missing or expired."
357
+ return finish(
358
+ errorResponse(
359
+ 409,
360
+ "hosted_admission_unavailable",
361
+ "The hosted admission token is missing or expired."
362
+ )
278
363
  );
279
364
  }
280
365
  if (
281
366
  admitted.sessionPublicId !== undefined &&
282
367
  admitted.sessionPublicId !== execution.sessionPublicId
283
368
  ) {
284
- return errorResponse(
285
- 409,
286
- "hosted_admission_session_mismatch",
287
- "The hosted admission token is already bound to another session."
369
+ return finish(
370
+ errorResponse(
371
+ 409,
372
+ "hosted_admission_session_mismatch",
373
+ "The hosted admission token is already bound to another session."
374
+ )
288
375
  );
289
376
  }
290
377
  admitted.sessionPublicId = execution.sessionPublicId;
@@ -321,7 +408,7 @@ export function registerHostedDeliveryRoute(input: {
321
408
  };
322
409
  })();
323
410
  const reply = await admitted.execution;
324
- return Response.json(reply.body, { status: reply.status });
411
+ return finish(Response.json(reply.body, { status: reply.status }));
325
412
  },
326
413
  });
327
414
  }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Managed-automation envelope slices by provider delivery id (plan 0002
3
+ * G2), recorded at hosted admission so channel code running the delivery's
4
+ * task (or session turn) can attach the customer's MCP servers through the
5
+ * control-plane relay. In-memory and TTL-bounded like the hosted pending-
6
+ * send table: the envelope slice carries names only (never credentials)
7
+ * and evaporates with the process.
8
+ *
9
+ * A leaf module (protocol type import only) so product channels can read
10
+ * it without pulling the hosted-delivery route — and its session-engine
11
+ * dependency graph — into their bundles.
12
+ *
13
+ * INTERNAL: first-party multi-tenant deployment plumbing. Deliberately
14
+ * excluded from the published `@cursor/july` npm package (see the `files`
15
+ * whitelist); consumed by internal deployments via relative source imports.
16
+ */
17
+
18
+ import type { HostedAdmissionManagedAutomation } from "./hosted-delivery-protocol.js";
19
+
20
+ const managedAutomationByDelivery = new Map<
21
+ string,
22
+ { managedAutomation: HostedAdmissionManagedAutomation; expiresAt: number }
23
+ >();
24
+ /** Long enough to outlive a slow review run kicked off by the delivery. */
25
+ const MANAGED_AUTOMATION_TTL_MS = 60 * 60_000;
26
+ const MANAGED_AUTOMATION_MAX_ENTRIES = 10_000;
27
+
28
+ export function recordHostedManagedAutomation(delivery: {
29
+ deliveryId: string;
30
+ managedAutomation?: HostedAdmissionManagedAutomation;
31
+ }): void {
32
+ if (delivery.managedAutomation === undefined) {
33
+ return;
34
+ }
35
+ const now = Date.now();
36
+ for (const [key, entry] of managedAutomationByDelivery) {
37
+ if (entry.expiresAt <= now) {
38
+ managedAutomationByDelivery.delete(key);
39
+ }
40
+ }
41
+ if (managedAutomationByDelivery.size >= MANAGED_AUTOMATION_MAX_ENTRIES) {
42
+ managedAutomationByDelivery.clear();
43
+ }
44
+ managedAutomationByDelivery.set(delivery.deliveryId, {
45
+ managedAutomation: delivery.managedAutomation,
46
+ expiresAt: now + MANAGED_AUTOMATION_TTL_MS,
47
+ });
48
+ }
49
+
50
+ /**
51
+ * The managed automation the control plane attributed to a hosted delivery,
52
+ * when the envelope carried one. Undefined for non-managed deliveries,
53
+ * expired entries, and non-hosted (webhook/stream) dispatch paths.
54
+ */
55
+ export function getHostedManagedAutomation(
56
+ deliveryId: string
57
+ ): HostedAdmissionManagedAutomation | undefined {
58
+ const entry = managedAutomationByDelivery.get(deliveryId);
59
+ if (entry === undefined) {
60
+ return undefined;
61
+ }
62
+ if (entry.expiresAt <= Date.now()) {
63
+ managedAutomationByDelivery.delete(deliveryId);
64
+ return undefined;
65
+ }
66
+ return entry.managedAutomation;
67
+ }
68
+
69
+ /** Drop recorded managed-automation slices (tests only). */
70
+ export function resetHostedManagedAutomationForTest(): void {
71
+ managedAutomationByDelivery.clear();
72
+ }
@@ -252,9 +252,9 @@ function buildToolMcpServer(
252
252
  * travels in the turn's MCP config or lands on the VM.
253
253
  *
254
254
  * The engine gates access twice, mirroring the authored server-tool path:
255
- * only bridgeable names (`isCloudBridgedConnection`) — `hostOnly`
256
- * connections and unknown names stay unreachable from a VM even with a
257
- * valid endpoint credential — and only while the bound session has a turn
255
+ * only bridgeable names (`isCloudBridgedConnection`) — unknown names
256
+ * stay unreachable from a VM even with a valid endpoint credential —
257
+ * and only while the bound session has a turn
258
258
  * in flight (`hasActiveTurn`), so a credential that persists on a VM after
259
259
  * its turn cannot keep calling host connectors. Listing forwards per
260
260
  * request, so a server that adds tools mid-session (`tools/list_changed`,
@@ -1,12 +1,13 @@
1
1
  /**
2
- * Host-side MCP clients for authored `agent/mcp-connections/*`.
2
+ * Host-side MCP clients for authored `agent/mcp-connections/*` and
3
+ * `agent/host-connections/*`.
3
4
  *
4
- * Every connection is always available in three places:
5
- * - the Cursor agent, via SDK `mcpServers` (local harness or cloud)
6
- * - the agent-serve host, for in-process server tools through
7
- * {@link HostMcpRegistry} on {@link ToolContext.host}.mcp
8
- * - channel / webhook route handlers through
9
- * {@link HostMcpRegistry} on {@link ChannelHandlerArgs.host}.mcp
5
+ * Model-visible connections (`mcp-connections/`) are available in three
6
+ * places: SDK `mcpServers`, in-process server tools through
7
+ * {@link HostMcpRegistry} on {@link ToolContext.host}.mcp, and channel /
8
+ * webhook handlers through {@link HostMcpRegistry} on
9
+ * {@link ChannelHandlerArgs.host}.mcp. Host connections skip the model
10
+ * and stay on `host.mcp` plus `mcp oauth`.
10
11
  */
11
12
 
12
13
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
@@ -37,7 +37,10 @@ export function collectPeerConnections(
37
37
  const bySlug = new Map<string, PeerConnectionRef[]>();
38
38
  for (const { slug, project } of mounts) {
39
39
  const refs: PeerConnectionRef[] = [];
40
- for (const connection of project.agent.connections) {
40
+ for (const connection of [
41
+ ...project.agent.connections,
42
+ ...(project.agent.hostConnections ?? []),
43
+ ]) {
41
44
  if (!isPeerConnectionTransport(connection.transport)) {
42
45
  continue;
43
46
  }
@@ -96,9 +96,7 @@ export function renderPlaygroundAsset(file: string): Response {
96
96
  }
97
97
 
98
98
  /** Slack surface summary for the host home / `GET /v1/agents`. */
99
- export type AgentIndexSlack =
100
- | { kind: "cursor-account"; handle: string }
101
- | { kind: "socket" };
99
+ export type AgentIndexSlack = { kind: "socket" };
102
100
 
103
101
  /** One row on the host home page and `GET /v1/agents`. */
104
102
  export interface AgentIndexEntry {
@@ -46,13 +46,13 @@ export function validateMountConnectionsConfig(args: {
46
46
  return;
47
47
  }
48
48
  const label = args.slug === "" ? args.project.name : args.slug;
49
- const hostOnlyNames = new Set(
50
- agent.connections
51
- .filter((connection) => connection.hostOnly === true)
52
- .map((connection) => connection.name)
49
+ const hostConnectionNames = new Set(
50
+ (args.project.agent.hostConnections ?? []).map(
51
+ (connection) => connection.name
52
+ )
53
53
  );
54
54
  const filteredRefs = args.accountRefs.filter(
55
- (ref) => ref.servers !== undefined && !hostOnlyNames.has(ref.name)
55
+ (ref) => ref.servers !== undefined && !hostConnectionNames.has(ref.name)
56
56
  );
57
57
  if (filteredRefs.length === 0) {
58
58
  return;
@@ -140,10 +140,8 @@ export function resolveMountConnections(args: {
140
140
 
141
141
  if (cloudCapable) {
142
142
  const hostOauthNames = agent.connections
143
- .filter(
144
- (connection) =>
145
- connection.hostOnly !== true &&
146
- isHostOauthConnectionTransport(connection.transport)
143
+ .filter((connection) =>
144
+ isHostOauthConnectionTransport(connection.transport)
147
145
  )
148
146
  .map((connection) => connection.name);
149
147
  if (hostOauthNames.length > 0) {
@@ -154,7 +152,7 @@ export function resolveMountConnections(args: {
154
152
  )}) reach cloud turns through the host connection bridge; their tokens stay on this serve host.`
155
153
  : `[agent-sdk] warning: agent "${label}" has host-OAuth MCP connections (${hostOauthNames.join(
156
154
  ", "
157
- )}) whose tokens live on this serve host; cloud-runtime turns omit them. Mark them \`hostOnly: true\` and call them from host tools, or drop \`oauth\` and authorize the server another way.`
155
+ )}) whose tokens live on this serve host; cloud-runtime turns omit them. Serve with a cloud tools URL so they reach turns through the host connection bridge, or drop \`oauth\` and authorize the server another way.`
158
156
  );
159
157
  }
160
158
  }
@@ -1,5 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import type { HostGitHubClient } from "../types.js";
3
+ import { parsePrUrl } from "./scm/pr-url.js";
3
4
 
4
5
  export type ReviewCommentPublisher = "local_gh" | "host_github" | "host_origin";
5
6
 
@@ -198,8 +199,15 @@ export type ReviewThreadResolverImplementation = {
198
199
  export function resolveScmReviewTarget(
199
200
  prUrl: string
200
201
  ): ScmReviewTarget | undefined {
201
- const parsed = parseReviewPrUrl(prUrl);
202
- return parsed.kind === "valid" ? parsed.value : undefined;
202
+ const parsed = parsePrUrl(prUrl);
203
+ if (parsed === undefined) {
204
+ return undefined;
205
+ }
206
+ return {
207
+ provider: parsed.provider,
208
+ repo: `${parsed.owner}/${parsed.repo}`,
209
+ prNumber: parsed.number,
210
+ };
203
211
  }
204
212
 
205
213
  /**
@@ -1243,117 +1251,6 @@ function skippedResolve(detail: string): ResolveReviewThreadsResult {
1243
1251
  };
1244
1252
  }
1245
1253
 
1246
- const ORIGIN_PR_PAGE_HOST_PATTERN = /^origin(-[a-z0-9]+)?\.cursor\.com$/i;
1247
-
1248
- /**
1249
- * Provider-neutral PR URL parse. GitHub.com plus the Origin page shapes
1250
- * `parsePrTarget` in security-review-lib accepts. Duplicated here so
1251
- * agent-serve does not import that package.
1252
- */
1253
- function parseReviewPrUrl(
1254
- prUrl: string
1255
- ):
1256
- | { kind: "valid"; value: ScmReviewTarget }
1257
- | { kind: "invalid"; detail: string } {
1258
- let url: URL;
1259
- try {
1260
- url = new URL(prUrl);
1261
- } catch (error) {
1262
- return {
1263
- kind: "invalid",
1264
- detail: `unparseable PR URL: ${error instanceof Error ? error.message : String(error)}`,
1265
- };
1266
- }
1267
-
1268
- const parts = url.pathname.split("/").filter(Boolean);
1269
- const hostname = url.hostname;
1270
-
1271
- if (hostname === "github.com" && parts.length >= 4 && parts[2] === "pull") {
1272
- const prNumber = Number(parts[3]);
1273
- if (Number.isInteger(prNumber) && prNumber > 0) {
1274
- return {
1275
- kind: "valid",
1276
- value: {
1277
- provider: "github",
1278
- repo: `${parts[0]}/${parts[1]}`,
1279
- prNumber,
1280
- },
1281
- };
1282
- }
1283
- }
1284
-
1285
- if (
1286
- ORIGIN_PR_PAGE_HOST_PATTERN.test(hostname) &&
1287
- parts.length >= 4 &&
1288
- parts[2] === "github"
1289
- ) {
1290
- const prNumber = Number(parts[3]);
1291
- if (Number.isInteger(prNumber) && prNumber > 0) {
1292
- return {
1293
- kind: "valid",
1294
- value: {
1295
- provider: "origin",
1296
- repo: `${parts[0]}/${parts[1]}`,
1297
- prNumber,
1298
- },
1299
- };
1300
- }
1301
- }
1302
-
1303
- if (
1304
- /^(www\.)?cursor\.com$/i.test(hostname) &&
1305
- parts[0] === "codebase" &&
1306
- parts.length >= 5 &&
1307
- parts[3] === "pull"
1308
- ) {
1309
- const prNumber = Number(parts[4]);
1310
- if (Number.isInteger(prNumber) && prNumber > 0) {
1311
- return {
1312
- kind: "valid",
1313
- value: {
1314
- provider: "origin",
1315
- repo: `${parts[1]}/${parts[2]}`,
1316
- prNumber,
1317
- },
1318
- };
1319
- }
1320
- }
1321
-
1322
- if (hostname === "review.cursor.com" && parts[0] === "pr") {
1323
- if (parts.length >= 5 && parts[3] === "github") {
1324
- const prNumber = Number(parts[4]);
1325
- if (Number.isInteger(prNumber) && prNumber > 0) {
1326
- return {
1327
- kind: "valid",
1328
- value: {
1329
- provider: "origin",
1330
- repo: `${parts[1]}/${parts[2]}`,
1331
- prNumber,
1332
- },
1333
- };
1334
- }
1335
- }
1336
- if (parts.length >= 4) {
1337
- const prNumber = Number(parts[3]);
1338
- if (Number.isInteger(prNumber) && prNumber > 0) {
1339
- return {
1340
- kind: "valid",
1341
- value: {
1342
- provider: "origin",
1343
- repo: `${parts[1]}/${parts[2]}`,
1344
- prNumber,
1345
- },
1346
- };
1347
- }
1348
- }
1349
- }
1350
-
1351
- return {
1352
- kind: "invalid",
1353
- detail: "unparseable PR URL: not a GitHub or Origin pull request",
1354
- };
1355
- }
1356
-
1357
1254
  function parseGithubPrUrl(
1358
1255
  prUrl: string
1359
1256
  ):