@cursor/july 0.1.107 → 0.1.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/AGENTS.md +2 -6
  2. package/README.md +13 -11
  3. package/dist/bin/agent-serve.js +30 -8
  4. package/dist/channels/bitbucket/api.d.ts +41 -0
  5. package/dist/channels/bitbucket/api.d.ts.map +1 -1
  6. package/dist/channels/bitbucket/api.js +260 -0
  7. package/dist/channels/bitbucket/binding.d.ts +4 -0
  8. package/dist/channels/bitbucket/binding.d.ts.map +1 -1
  9. package/dist/channels/bitbucket/binding.js +16 -0
  10. package/dist/channels/bitbucket/index.d.ts +1 -1
  11. package/dist/channels/bitbucket/index.d.ts.map +1 -1
  12. package/dist/channels/bitbucket/index.js +1 -1
  13. package/dist/channels/github/github-channel.js +8 -5
  14. package/dist/channels/github/types.d.ts +5 -1
  15. package/dist/channels/github/types.d.ts.map +1 -1
  16. package/dist/channels/gitlab/api.d.ts +27 -0
  17. package/dist/channels/gitlab/api.d.ts.map +1 -1
  18. package/dist/channels/gitlab/api.js +88 -0
  19. package/dist/channels/gitlab/binding.d.ts +5 -0
  20. package/dist/channels/gitlab/binding.d.ts.map +1 -1
  21. package/dist/channels/gitlab/binding.js +10 -0
  22. package/dist/channels/gitlab/index.d.ts +1 -1
  23. package/dist/channels/gitlab/index.d.ts.map +1 -1
  24. package/dist/channels/gitlab/index.js +1 -1
  25. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  26. package/dist/channels/origin/origin-channel.js +27 -13
  27. package/dist/channels/origin/types.d.ts +5 -1
  28. package/dist/channels/origin/types.d.ts.map +1 -1
  29. package/dist/channels/slack/dispatch.d.ts +10 -0
  30. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  31. package/dist/channels/slack/dispatch.js +20 -3
  32. package/dist/channels/slack/slack-channel.d.ts +12 -5
  33. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  34. package/dist/channels/slack/slack-channel.js +59 -8
  35. package/dist/channels.d.ts +45 -0
  36. package/dist/channels.d.ts.map +1 -1
  37. package/dist/channels.js +106 -7
  38. package/dist/connections.d.ts +2 -1
  39. package/dist/connections.d.ts.map +1 -1
  40. package/dist/connections.js +2 -1
  41. package/dist/docs/404.html +2 -2
  42. package/dist/docs/assets/{app.CtuckIiL.js → app.Cr-wVbnB.js} +1 -1
  43. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.D0KbSkJn.js} +2 -2
  44. package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.D0KbSkJn.lean.js} +1 -1
  45. package/dist/docs/assets/chunks/@localSearchIndexroot.CFVQ4S17.js +1 -0
  46. package/dist/docs/assets/chunks/{VPLocalSearchBox.Bkkhnu8K.js → VPLocalSearchBox.CVQERt56.js} +1 -1
  47. package/dist/docs/assets/chunks/{theme.DhpIe0Pa.js → theme.Dnsd3XOn.js} +2 -2
  48. package/dist/docs/assets/concepts.md.B4o63Gul.js +1 -0
  49. package/dist/docs/assets/{deployment.md.MFPKqsqI.js → deployment.md.JenwuCCB.js} +4 -4
  50. package/dist/docs/assets/{deployment.md.MFPKqsqI.lean.js → deployment.md.JenwuCCB.lean.js} +1 -1
  51. package/dist/docs/assets/evals.md.C7JLjoEP.js +211 -0
  52. package/dist/docs/assets/evals.md.C7JLjoEP.lean.js +1 -0
  53. package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.js +10 -0
  54. package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.lean.js +1 -0
  55. package/dist/docs/assets/guides_cloud-agents.md.BsloyHdY.js +9 -0
  56. package/dist/docs/assets/{guides_cloud-agents.md.DS8RIjwx.lean.js → guides_cloud-agents.md.BsloyHdY.lean.js} +1 -1
  57. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.js → guides_github.md.TZaTZlfz.js} +13 -3
  58. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.lean.js → guides_github.md.TZaTZlfz.lean.js} +1 -1
  59. package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.js +14 -0
  60. package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.lean.js +1 -0
  61. package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.js → guides_grokbot-agents.md.DyV-WArv.js} +1 -1
  62. package/dist/docs/assets/guides_improve.md.BGVk32bK.js +14 -0
  63. package/dist/docs/assets/guides_improve.md.BGVk32bK.lean.js +1 -0
  64. package/dist/docs/assets/{guides_slack.md.9oHPye9o.js → guides_slack.md.D4RVMM4G.js} +3 -3
  65. package/dist/docs/assets/{guides_slack.md.9oHPye9o.lean.js → guides_slack.md.D4RVMM4G.lean.js} +1 -1
  66. package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.CJK484ex.js} +2 -2
  67. package/dist/docs/assets/{hillclimbing.md.CpTGTCle.js → hillclimbing.md.BOiVo1tf.js} +1 -1
  68. package/dist/docs/assets/index.md.DD9Q2XuJ.js +5 -0
  69. package/dist/docs/assets/{index.md.BW_6tOgR.lean.js → index.md.DD9Q2XuJ.lean.js} +1 -1
  70. package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.js → reference_agent-config.md.CvoL6pof.js} +1 -1
  71. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js} +2 -2
  72. package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.CAo-iK4j.lean.js} +1 -1
  73. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.js → reference_cli.md.Deg7849l.js} +7 -7
  74. package/dist/docs/assets/{reference_cli.md.Dm67hd2D.lean.js → reference_cli.md.Deg7849l.lean.js} +1 -1
  75. package/dist/docs/assets/{reference_connections.md.Di6jJAXF.js → reference_connections.md.BojkC6c5.js} +1 -1
  76. package/dist/docs/assets/{reference_extensions.md.CGmMLblt.js → reference_extensions.md.ZAVUyuEX.js} +3 -3
  77. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.BlM_bOg6.js} +3 -3
  78. package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.BlM_bOg6.lean.js} +1 -1
  79. package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.BwaCo-VO.js} +1 -1
  80. package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.DLnoaczX.js} +1 -1
  81. package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.DLnoaczX.lean.js} +1 -1
  82. package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.js → reference_project-layout.md.BEU8MtQV.js} +3 -3
  83. package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.BEU8MtQV.lean.js} +1 -1
  84. package/dist/docs/assets/reference_sessions.md.CyXV1MUw.js +1 -0
  85. package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.js → scaffolding-agents.md.Kctn3OVb.js} +1 -1
  86. package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.js → skills_create-agent.md.Q3h6Je-e.js} +1 -1
  87. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.js → skills_debug.md.CVjCXMFF.js} +1 -1
  88. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.lean.js → skills_debug.md.CVjCXMFF.lean.js} +1 -1
  89. package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.js +35 -0
  90. package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.lean.js +1 -0
  91. package/dist/docs/assets/skills_evals.md.DFxYPErF.js +25 -0
  92. package/dist/docs/assets/skills_evals.md.DFxYPErF.lean.js +1 -0
  93. package/dist/docs/assets/skills_framework-map.md.BxLSOhSY.js +1 -0
  94. package/dist/docs/assets/{skills_framework-map.md.haibFyoB.lean.js → skills_framework-map.md.BxLSOhSY.lean.js} +1 -1
  95. package/dist/docs/assets/{skills_github.md.D0JahM8c.js → skills_github.md.hgFX_oKY.js} +1 -1
  96. package/dist/docs/assets/skills_index.md.DL7EHaQ-.js +1 -0
  97. package/dist/docs/assets/skills_index.md.DL7EHaQ-.lean.js +1 -0
  98. package/dist/docs/assets/{storage.md.BOHeqk2M.js → storage.md.BUrhJ-Zz.js} +4 -4
  99. package/dist/docs/assets/{storage.md.BOHeqk2M.lean.js → storage.md.BUrhJ-Zz.lean.js} +1 -1
  100. package/dist/docs/assets/troubleshooting.md.CYEAO9bM.js +1 -0
  101. package/dist/docs/building-with-agents.html +5 -5
  102. package/dist/docs/building-with-agents.md +3 -2
  103. package/dist/docs/concepts.html +5 -5
  104. package/dist/docs/concepts.md +2 -4
  105. package/dist/docs/deployment.html +7 -7
  106. package/dist/docs/deployment.md +7 -2
  107. package/dist/docs/evals.html +161 -35
  108. package/dist/docs/evals.md +612 -296
  109. package/dist/docs/guides/agent-to-agent.html +4 -4
  110. package/dist/docs/guides/bitbucket.html +36 -0
  111. package/dist/docs/guides/bitbucket.md +84 -0
  112. package/dist/docs/guides/cloud-agents.html +6 -6
  113. package/dist/docs/guides/cloud-agents.md +4 -3
  114. package/dist/docs/guides/convert-automation.html +4 -4
  115. package/dist/docs/guides/github.html +17 -7
  116. package/dist/docs/guides/github.md +33 -1
  117. package/dist/docs/guides/gitlab.html +40 -0
  118. package/dist/docs/guides/gitlab.md +92 -0
  119. package/dist/docs/guides/grokbot-agents.html +6 -6
  120. package/dist/docs/guides/grokbot-agents.md +2 -2
  121. package/dist/docs/guides/human-in-the-loop.html +4 -4
  122. package/dist/docs/guides/improve.html +40 -0
  123. package/dist/docs/guides/improve.md +91 -0
  124. package/dist/docs/guides/mcp-oauth.html +4 -4
  125. package/dist/docs/guides/opentelemetry.html +5 -5
  126. package/dist/docs/guides/slack.html +7 -7
  127. package/dist/docs/guides/slack.md +2 -1
  128. package/dist/docs/guides/webhooks.html +6 -6
  129. package/dist/docs/guides/webhooks.md +4 -2
  130. package/dist/docs/hashmap.json +1 -1
  131. package/dist/docs/hillclimbing.html +6 -6
  132. package/dist/docs/hillclimbing.md +2 -2
  133. package/dist/docs/index.html +6 -6
  134. package/dist/docs/index.md +14 -6
  135. package/dist/docs/llms-full.txt +1274 -814
  136. package/dist/docs/llms.txt +7 -5
  137. package/dist/docs/quickstart.html +4 -4
  138. package/dist/docs/reference/agent-config.html +6 -6
  139. package/dist/docs/reference/agent-config.md +5 -2
  140. package/dist/docs/reference/artifacts.html +4 -4
  141. package/dist/docs/reference/channels.html +6 -6
  142. package/dist/docs/reference/channels.md +16 -3
  143. package/dist/docs/reference/cli.html +11 -11
  144. package/dist/docs/reference/cli.md +24 -15
  145. package/dist/docs/reference/connections.html +6 -6
  146. package/dist/docs/reference/connections.md +2 -1
  147. package/dist/docs/reference/extensions.html +8 -8
  148. package/dist/docs/reference/extensions.md +2 -3
  149. package/dist/docs/reference/hooks.html +7 -7
  150. package/dist/docs/reference/hooks.md +9 -12
  151. package/dist/docs/reference/http-api.html +6 -6
  152. package/dist/docs/reference/http-api.md +2 -3
  153. package/dist/docs/reference/instructions.html +4 -4
  154. package/dist/docs/reference/playground.html +5 -5
  155. package/dist/docs/reference/playground.md +0 -4
  156. package/dist/docs/reference/project-layout.html +7 -7
  157. package/dist/docs/reference/project-layout.md +1 -8
  158. package/dist/docs/reference/prompt.html +4 -4
  159. package/dist/docs/reference/result.html +4 -4
  160. package/dist/docs/reference/schedules.html +4 -4
  161. package/dist/docs/reference/sessions.html +5 -5
  162. package/dist/docs/reference/sessions.md +1 -2
  163. package/dist/docs/reference/skills.html +4 -4
  164. package/dist/docs/reference/subagents.html +4 -4
  165. package/dist/docs/reference/tools.html +4 -4
  166. package/dist/docs/scaffolding-agents.html +5 -5
  167. package/dist/docs/scaffolding-agents.md +2 -1
  168. package/dist/docs/skills/create-agent.html +6 -6
  169. package/dist/docs/skills/create-agent.md +1 -1
  170. package/dist/docs/skills/debug.html +5 -5
  171. package/dist/docs/skills/debug.md +1 -1
  172. package/dist/docs/skills/deploy.html +61 -0
  173. package/dist/docs/skills/deploy.md +161 -0
  174. package/dist/docs/skills/evals.html +8 -8
  175. package/dist/docs/skills/evals.md +44 -6
  176. package/dist/docs/skills/framework-map.html +5 -5
  177. package/dist/docs/skills/framework-map.md +5 -4
  178. package/dist/docs/skills/github.html +6 -6
  179. package/dist/docs/skills/github.md +1 -1
  180. package/dist/docs/skills/hillclimb.html +4 -4
  181. package/dist/docs/skills/index.html +6 -6
  182. package/dist/docs/skills/index.md +1 -1
  183. package/dist/docs/skills/mcp-auth.html +4 -4
  184. package/dist/docs/skills/otel.html +4 -4
  185. package/dist/docs/skills/setup-slack.html +4 -4
  186. package/dist/docs/storage.html +8 -8
  187. package/dist/docs/storage.md +15 -24
  188. package/dist/docs/templates/agentic-owners.html +4 -4
  189. package/dist/docs/templates/agents-md.html +4 -4
  190. package/dist/docs/templates/code-wiki.html +4 -4
  191. package/dist/docs/templates/demo.html +4 -4
  192. package/dist/docs/templates/grokbot-agents.html +4 -4
  193. package/dist/docs/templates/pr-autofixer.html +4 -4
  194. package/dist/docs/templates/security-help.html +4 -4
  195. package/dist/docs/templates/security-reviewer.html +4 -4
  196. package/dist/docs/templates/triage.html +4 -4
  197. package/dist/docs/troubleshooting.html +5 -5
  198. package/dist/docs/troubleshooting.md +1 -1
  199. package/dist/extensions/improve/extension.d.ts +46 -0
  200. package/dist/extensions/improve/extension.d.ts.map +1 -0
  201. package/dist/extensions/improve/extension.js +41 -0
  202. package/dist/extensions/improve/skills/yourself.d.ts +4 -0
  203. package/dist/extensions/improve/skills/yourself.d.ts.map +1 -0
  204. package/dist/extensions/improve/skills/yourself.js +43 -0
  205. package/dist/extensions.d.ts +2 -3
  206. package/dist/extensions.d.ts.map +1 -1
  207. package/dist/extensions.js +2 -5
  208. package/dist/index.d.ts +2 -3
  209. package/dist/index.d.ts.map +1 -1
  210. package/dist/index.js +1 -2
  211. package/dist/internal/authored-alias-hooks.d.ts +5 -0
  212. package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
  213. package/dist/internal/authored-alias-hooks.js +17 -0
  214. package/dist/internal/authored-loaders.d.ts +4 -0
  215. package/dist/internal/authored-loaders.d.ts.map +1 -1
  216. package/dist/internal/authored-loaders.js +21 -2
  217. package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
  218. package/dist/internal/builtin-tools/artifacts.js +2 -3
  219. package/dist/internal/channel-route-dispatch.d.ts +13 -0
  220. package/dist/internal/channel-route-dispatch.d.ts.map +1 -0
  221. package/dist/internal/channel-route-dispatch.js +62 -0
  222. package/dist/internal/channel-state.d.ts +17 -0
  223. package/dist/internal/channel-state.d.ts.map +1 -0
  224. package/dist/internal/channel-state.js +78 -0
  225. package/dist/internal/cli-ax.d.ts +8 -2
  226. package/dist/internal/cli-ax.d.ts.map +1 -1
  227. package/dist/internal/cli-ax.js +100 -3
  228. package/dist/internal/cli-cursor.d.ts.map +1 -1
  229. package/dist/internal/cli-cursor.js +2 -0
  230. package/dist/internal/cli-deploy.d.ts.map +1 -1
  231. package/dist/internal/cli-deploy.js +38 -14
  232. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  233. package/dist/internal/cli-mcp-oauth.js +15 -0
  234. package/dist/internal/cli-mcp.d.ts.map +1 -1
  235. package/dist/internal/cli-mcp.js +12 -0
  236. package/dist/internal/cli-slack.d.ts.map +1 -1
  237. package/dist/internal/cli-slack.js +8 -2
  238. package/dist/internal/continuation-channel.d.ts.map +1 -1
  239. package/dist/internal/continuation-channel.js +2 -2
  240. package/dist/internal/continuation-identity.js +8 -3
  241. package/dist/internal/cursor/credentials.d.ts +8 -2
  242. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  243. package/dist/internal/cursor/credentials.js +27 -5
  244. package/dist/internal/deploy-client.d.ts +27 -0
  245. package/dist/internal/deploy-client.d.ts.map +1 -1
  246. package/dist/internal/deploy-client.js +32 -0
  247. package/dist/internal/deploy-manifest.d.ts +23 -0
  248. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  249. package/dist/internal/deploy-manifest.js +84 -1
  250. package/dist/internal/describe-error.d.ts +1 -0
  251. package/dist/internal/describe-error.d.ts.map +1 -1
  252. package/dist/internal/describe-error.js +25 -0
  253. package/dist/internal/discovery/agent.d.ts +1 -1
  254. package/dist/internal/discovery/agent.d.ts.map +1 -1
  255. package/dist/internal/discovery/agent.js +0 -5
  256. package/dist/internal/discovery/extension-overlay.d.ts +1 -2
  257. package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
  258. package/dist/internal/discovery/extension-overlay.js +0 -14
  259. package/dist/internal/discovery/extensions.d.ts +1 -2
  260. package/dist/internal/discovery/extensions.d.ts.map +1 -1
  261. package/dist/internal/discovery/extensions.js +4 -22
  262. package/dist/internal/discovery/info.d.ts.map +1 -1
  263. package/dist/internal/discovery/info.js +42 -24
  264. package/dist/internal/discovery/modules.js +0 -1
  265. package/dist/internal/discovery/project.d.ts.map +1 -1
  266. package/dist/internal/discovery/project.js +0 -16
  267. package/dist/internal/eval-runner.js +0 -1
  268. package/dist/internal/framework-file-storage.d.ts +4 -5
  269. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  270. package/dist/internal/framework-file-storage.js +4 -5
  271. package/dist/internal/framework-storage-selection.d.ts +2 -2
  272. package/dist/internal/framework-storage-selection.js +2 -2
  273. package/dist/internal/guest-network.d.ts +4 -10
  274. package/dist/internal/guest-network.d.ts.map +1 -1
  275. package/dist/internal/guest-network.js +42 -26
  276. package/dist/internal/hosted-admission-adapter.d.ts +2 -0
  277. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  278. package/dist/internal/hosted-catch-protocol.d.ts +51 -0
  279. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -0
  280. package/dist/internal/hosted-catch-protocol.js +103 -0
  281. package/dist/internal/hosted-catch.d.ts +40 -0
  282. package/dist/internal/hosted-catch.d.ts.map +1 -0
  283. package/dist/internal/hosted-catch.js +149 -0
  284. package/dist/internal/hosted-delivery-protocol.d.ts +41 -0
  285. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  286. package/dist/internal/hosted-delivery-protocol.js +249 -0
  287. package/dist/internal/hosted-delivery.d.ts +10 -1
  288. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  289. package/dist/internal/hosted-delivery.js +100 -22
  290. package/dist/internal/hosted-execution-diag.d.ts +4 -1
  291. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  292. package/dist/internal/hosted-execution-diag.js +13 -4
  293. package/dist/internal/hosted-execution-flush.d.ts +3 -0
  294. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  295. package/dist/internal/hosted-execution-flush.js +2 -4
  296. package/dist/internal/http-control-plane-session.d.ts +30 -0
  297. package/dist/internal/http-control-plane-session.d.ts.map +1 -0
  298. package/dist/internal/http-control-plane-session.js +83 -0
  299. package/dist/internal/init-scaffold.d.ts.map +1 -1
  300. package/dist/internal/init-scaffold.js +1 -2
  301. package/dist/internal/install-cursor-skills.d.ts +5 -2
  302. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  303. package/dist/internal/install-cursor-skills.js +25 -5
  304. package/dist/internal/legacy-command-guard.d.ts +22 -0
  305. package/dist/internal/legacy-command-guard.d.ts.map +1 -0
  306. package/dist/internal/legacy-command-guard.js +51 -0
  307. package/dist/internal/platform-timers.d.ts +7 -0
  308. package/dist/internal/platform-timers.d.ts.map +1 -1
  309. package/dist/internal/platform-timers.js +139 -0
  310. package/dist/internal/reminder-control-plane-protocol.d.ts +2 -0
  311. package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -1
  312. package/dist/internal/reminder-control-plane-protocol.js +9 -2
  313. package/dist/internal/reminder-runner.d.ts +8 -0
  314. package/dist/internal/reminder-runner.d.ts.map +1 -1
  315. package/dist/internal/reminder-runner.js +36 -9
  316. package/dist/internal/resolve-prod-target.d.ts +2 -0
  317. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  318. package/dist/internal/resolve-prod-target.js +13 -0
  319. package/dist/internal/run-client.d.ts +1 -1
  320. package/dist/internal/sdk-runner.d.ts.map +1 -1
  321. package/dist/internal/sdk-runner.js +5 -4
  322. package/dist/internal/server.d.ts.map +1 -1
  323. package/dist/internal/server.js +57 -70
  324. package/dist/internal/session-engine.d.ts +7 -41
  325. package/dist/internal/session-engine.d.ts.map +1 -1
  326. package/dist/internal/session-engine.js +110 -227
  327. package/dist/internal/storage-coordinator.d.ts +5 -19
  328. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  329. package/dist/internal/storage-coordinator.js +3 -62
  330. package/dist/internal/storage-roles.d.ts +4 -9
  331. package/dist/internal/storage-roles.d.ts.map +1 -1
  332. package/dist/internal/storage-roles.js +2 -2
  333. package/dist/playground/assets/index-Bhxzrcf6.css +1 -0
  334. package/dist/playground/assets/index-CqLX5uF3.js +67 -0
  335. package/dist/playground/index.html +2 -2
  336. package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
  337. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
  338. package/dist/storage-backends/cursor-hosted-v2.js +4 -5
  339. package/dist/storage-backends/cursor-hosted.d.ts +7 -2
  340. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  341. package/dist/storage-backends/cursor-hosted.js +29 -31
  342. package/dist/storage-backends/file-kv.d.ts +9 -12
  343. package/dist/storage-backends/file-kv.d.ts.map +1 -1
  344. package/dist/storage-backends/file-kv.js +11 -47
  345. package/dist/storage-protocol.d.ts +3 -11
  346. package/dist/storage-protocol.d.ts.map +1 -1
  347. package/dist/storage-protocol.js +3 -11
  348. package/dist/storage.d.ts +8 -36
  349. package/dist/storage.d.ts.map +1 -1
  350. package/dist/storage.js +8 -44
  351. package/dist/types.d.ts +53 -62
  352. package/dist/types.d.ts.map +1 -1
  353. package/docs/README.md +14 -6
  354. package/docs/building-with-agents.md +3 -2
  355. package/docs/concepts.md +2 -4
  356. package/docs/deployment.md +7 -2
  357. package/docs/evals.md +613 -297
  358. package/docs/guides/bitbucket.md +89 -0
  359. package/docs/guides/cloud-agents.md +4 -3
  360. package/docs/guides/github.md +33 -1
  361. package/docs/guides/gitlab.md +97 -0
  362. package/docs/guides/grokbot-agents.md +2 -2
  363. package/docs/guides/improve.md +96 -0
  364. package/docs/guides/slack.md +2 -1
  365. package/docs/guides/webhooks.md +4 -2
  366. package/docs/hillclimbing.md +2 -2
  367. package/docs/reference/agent-config.md +5 -2
  368. package/docs/reference/channels.md +16 -3
  369. package/docs/reference/cli.md +24 -15
  370. package/docs/reference/connections.md +2 -1
  371. package/docs/reference/extensions.md +2 -3
  372. package/docs/reference/hooks.md +9 -12
  373. package/docs/reference/http-api.md +2 -3
  374. package/docs/reference/playground.md +0 -4
  375. package/docs/reference/project-layout.md +1 -8
  376. package/docs/reference/sessions.md +1 -2
  377. package/docs/scaffolding-agents.md +2 -1
  378. package/docs/skills/index.md +2 -2
  379. package/docs/storage.md +15 -24
  380. package/docs/troubleshooting.md +1 -1
  381. package/package.json +8 -7
  382. package/skills/create-agent/SKILL.md +1 -1
  383. package/skills/debug/SKILL.md +1 -1
  384. package/skills/deploy/SKILL.md +169 -0
  385. package/skills/evals/SKILL.md +45 -8
  386. package/skills/framework-map/SKILL.md +5 -4
  387. package/skills/github/SKILL.md +1 -1
  388. package/src/bin/agent-serve.ts +27 -2
  389. package/src/channels/bitbucket/api.ts +341 -0
  390. package/src/channels/bitbucket/binding.ts +25 -0
  391. package/src/channels/bitbucket/index.ts +2 -0
  392. package/src/channels/github/github-channel.ts +8 -8
  393. package/src/channels/github/types.ts +5 -0
  394. package/src/channels/gitlab/api.ts +123 -0
  395. package/src/channels/gitlab/binding.ts +12 -0
  396. package/src/channels/gitlab/index.ts +1 -0
  397. package/src/channels/origin/origin-channel.ts +29 -13
  398. package/src/channels/origin/types.ts +5 -0
  399. package/src/channels/slack/dispatch.ts +30 -0
  400. package/src/channels/slack/slack-channel.ts +69 -7
  401. package/src/channels.ts +157 -10
  402. package/src/connections.ts +2 -1
  403. package/src/extensions/improve/extension.ts +70 -0
  404. package/src/extensions/improve/skills/yourself.ts +50 -0
  405. package/src/extensions.ts +2 -6
  406. package/src/index.ts +0 -3
  407. package/src/internal/authored-alias-hooks.ts +32 -0
  408. package/src/internal/authored-loaders.ts +26 -2
  409. package/src/internal/builtin-tools/artifacts.ts +2 -3
  410. package/src/internal/channel-route-dispatch.ts +66 -0
  411. package/src/internal/channel-state.ts +96 -0
  412. package/src/internal/cli-ax.ts +111 -3
  413. package/src/internal/cli-cursor.ts +4 -1
  414. package/src/internal/cli-deploy.ts +50 -10
  415. package/src/internal/cli-mcp-oauth.ts +18 -0
  416. package/src/internal/cli-mcp.ts +11 -0
  417. package/src/internal/cli-slack.ts +15 -2
  418. package/src/internal/continuation-channel.ts +2 -1
  419. package/src/internal/continuation-identity.ts +10 -2
  420. package/src/internal/cursor/credentials.ts +35 -7
  421. package/src/internal/deploy-client.ts +54 -0
  422. package/src/internal/deploy-manifest.ts +115 -1
  423. package/src/internal/describe-error.ts +28 -0
  424. package/src/internal/discovery/agent.ts +1 -7
  425. package/src/internal/discovery/extension-overlay.ts +0 -18
  426. package/src/internal/discovery/extensions.ts +2 -26
  427. package/src/internal/discovery/info.ts +3 -13
  428. package/src/internal/discovery/modules.ts +0 -1
  429. package/src/internal/discovery/project.ts +0 -16
  430. package/src/internal/eval-runner.ts +0 -1
  431. package/src/internal/framework-file-storage.ts +4 -5
  432. package/src/internal/framework-storage-selection.ts +2 -2
  433. package/src/internal/guest-network.ts +43 -29
  434. package/src/internal/hosted-admission-adapter.ts +2 -0
  435. package/src/internal/hosted-catch-protocol.ts +130 -0
  436. package/src/internal/hosted-catch.ts +192 -0
  437. package/src/internal/hosted-delivery-protocol.ts +387 -0
  438. package/src/internal/hosted-delivery.ts +155 -22
  439. package/src/internal/hosted-execution-diag.ts +21 -3
  440. package/src/internal/hosted-execution-flush.ts +6 -3
  441. package/src/internal/http-control-plane-session.ts +104 -0
  442. package/src/internal/init-scaffold.ts +1 -2
  443. package/src/internal/install-cursor-skills.ts +38 -5
  444. package/src/internal/legacy-command-guard.ts +59 -0
  445. package/src/internal/platform-timers.ts +191 -0
  446. package/src/internal/reminder-control-plane-protocol.ts +15 -2
  447. package/src/internal/reminder-runner.ts +60 -9
  448. package/src/internal/resolve-prod-target.ts +15 -0
  449. package/src/internal/run-client.ts +1 -1
  450. package/src/internal/sdk-runner.ts +3 -2
  451. package/src/internal/server.ts +89 -95
  452. package/src/internal/session-engine.ts +155 -285
  453. package/src/internal/storage-coordinator.ts +5 -76
  454. package/src/internal/storage-roles.ts +4 -9
  455. package/src/storage-backends/cursor-hosted-v2.ts +4 -7
  456. package/src/storage-backends/cursor-hosted.ts +40 -38
  457. package/src/storage-backends/file-kv.ts +10 -51
  458. package/src/storage-protocol.ts +3 -17
  459. package/src/storage.ts +10 -101
  460. package/src/types.ts +58 -62
  461. package/templates/demo/README.md +10 -6
  462. package/templates/demo/agent/channels/github.ts +2 -0
  463. package/templates/demo/agent/channels/queue.ts +6 -2
  464. package/templates/demo/agent/lib/repos.ts +5 -0
  465. package/templates/demo/init.json +25 -0
  466. package/dist/ab.d.ts +0 -209
  467. package/dist/ab.d.ts.map +0 -1
  468. package/dist/ab.js +0 -246
  469. package/dist/docs/ab.html +0 -80
  470. package/dist/docs/ab.md +0 -332
  471. package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
  472. package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
  473. package/dist/docs/assets/chunks/@localSearchIndexroot.DXXZxiMv.js +0 -1
  474. package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
  475. package/dist/docs/assets/evals.md.CbMoebP1.js +0 -85
  476. package/dist/docs/assets/evals.md.CbMoebP1.lean.js +0 -1
  477. package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +0 -9
  478. package/dist/docs/assets/index.md.BW_6tOgR.js +0 -5
  479. package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
  480. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
  481. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
  482. package/dist/docs/assets/skills_evals.md.723kpUmA.js +0 -25
  483. package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +0 -1
  484. package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +0 -1
  485. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
  486. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
  487. package/dist/docs/assets/troubleshooting.md.Cus_YZga.js +0 -1
  488. package/dist/docs/skills/ab.html +0 -52
  489. package/dist/docs/skills/ab.md +0 -50
  490. package/dist/internal/ab-collector.d.ts +0 -44
  491. package/dist/internal/ab-collector.d.ts.map +0 -1
  492. package/dist/internal/ab-collector.js +0 -142
  493. package/dist/internal/ab-fold.d.ts +0 -36
  494. package/dist/internal/ab-fold.d.ts.map +0 -1
  495. package/dist/internal/ab-fold.js +0 -175
  496. package/dist/internal/ab-snapshot.d.ts +0 -68
  497. package/dist/internal/ab-snapshot.d.ts.map +0 -1
  498. package/dist/internal/ab-snapshot.js +0 -208
  499. package/dist/internal/discovery/ab.d.ts +0 -9
  500. package/dist/internal/discovery/ab.d.ts.map +0 -1
  501. package/dist/internal/discovery/ab.js +0 -113
  502. package/dist/playground/assets/index-Bq2HpEQB.js +0 -67
  503. package/dist/playground/assets/index-CZKKNlmb.css +0 -1
  504. package/docs/ab.md +0 -337
  505. package/skills/ab/SKILL.md +0 -58
  506. package/src/ab.ts +0 -430
  507. package/src/internal/ab-collector.ts +0 -200
  508. package/src/internal/ab-fold.ts +0 -232
  509. package/src/internal/ab-snapshot.ts +0 -331
  510. package/src/internal/discovery/ab.ts +0 -131
  511. /package/dist/docs/assets/{concepts.md.DgEcZOfT.lean.js → concepts.md.B4o63Gul.lean.js} +0 -0
  512. /package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.lean.js → guides_grokbot-agents.md.DyV-WArv.lean.js} +0 -0
  513. /package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.CJK484ex.lean.js} +0 -0
  514. /package/dist/docs/assets/{hillclimbing.md.CpTGTCle.lean.js → hillclimbing.md.BOiVo1tf.lean.js} +0 -0
  515. /package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.lean.js → reference_agent-config.md.CvoL6pof.lean.js} +0 -0
  516. /package/dist/docs/assets/{reference_connections.md.Di6jJAXF.lean.js → reference_connections.md.BojkC6c5.lean.js} +0 -0
  517. /package/dist/docs/assets/{reference_extensions.md.CGmMLblt.lean.js → reference_extensions.md.ZAVUyuEX.lean.js} +0 -0
  518. /package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.BwaCo-VO.lean.js} +0 -0
  519. /package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.CyXV1MUw.lean.js} +0 -0
  520. /package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.lean.js → scaffolding-agents.md.Kctn3OVb.lean.js} +0 -0
  521. /package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.lean.js → skills_create-agent.md.Q3h6Je-e.lean.js} +0 -0
  522. /package/dist/docs/assets/{skills_github.md.D0JahM8c.lean.js → skills_github.md.hgFX_oKY.lean.js} +0 -0
  523. /package/dist/docs/assets/{troubleshooting.md.Cus_YZga.lean.js → troubleshooting.md.CYEAO9bM.lean.js} +0 -0
@@ -92,6 +92,35 @@ export interface GitLabClient {
92
92
  request<T = unknown>(input: GitLabRequestInput): Promise<T>;
93
93
  }
94
94
 
95
+ export interface GitLabApiMergeRequest {
96
+ iid: number;
97
+ title?: string;
98
+ description?: string;
99
+ state?: string;
100
+ draft?: boolean;
101
+ webUrl?: string;
102
+ headSha?: string;
103
+ sourceBranch?: string;
104
+ targetBranch?: string;
105
+ authorUsername?: string;
106
+ baseSha?: string;
107
+ changedFilesCount?: number;
108
+ }
109
+
110
+ export interface GitLabApiMergeRequestDiff {
111
+ oldPath: string;
112
+ newPath: string;
113
+ patch?: string;
114
+ status: "added" | "modified" | "removed" | "renamed";
115
+ }
116
+
117
+ /** Project-bound merge-request reads shared by GitLab agents. */
118
+ export interface GitLabApi {
119
+ getMergeRequest(iid: number): Promise<GitLabApiMergeRequest>;
120
+ getMergeBaseSha(base: string, headSha: string): Promise<string | undefined>;
121
+ listMergeRequestDiffs(iid: number): Promise<GitLabApiMergeRequestDiff[]>;
122
+ }
123
+
95
124
  function envValue(value: string | undefined): string | undefined {
96
125
  const trimmed = value?.trim();
97
126
  return trimmed === undefined || trimmed === "" ? undefined : trimmed;
@@ -136,6 +165,100 @@ export function gitlabProjectPathSegment(project: number | string): string {
136
165
  : encodeURIComponent(project.replace(/^\/+|\/+$/g, ""));
137
166
  }
138
167
 
168
+ function asRecord(value: unknown): Record<string, unknown> | undefined {
169
+ return typeof value === "object" && value !== null && !Array.isArray(value)
170
+ ? (value as Record<string, unknown>)
171
+ : undefined;
172
+ }
173
+
174
+ function nonEmptyString(value: unknown): string | undefined {
175
+ return typeof value === "string" && value !== "" ? value : undefined;
176
+ }
177
+
178
+ const GITLAB_DIFFS_PER_PAGE = 100;
179
+
180
+ export function createGitLabApi(
181
+ client: Pick<GitLabClient, "request">,
182
+ project: number | string
183
+ ): GitLabApi {
184
+ const projectPath = `/projects/${gitlabProjectPathSegment(project)}`;
185
+ return {
186
+ async getMergeRequest(iid) {
187
+ const raw = await client.request<Record<string, unknown>>({
188
+ method: "GET",
189
+ path: `${projectPath}/merge_requests/${iid}`,
190
+ });
191
+ const diffRefs = asRecord(raw.diff_refs);
192
+ const changesCount = nonEmptyString(raw.changes_count);
193
+ return {
194
+ iid: (raw.iid as number | null | undefined) ?? iid,
195
+ title: raw.title as string | undefined,
196
+ description:
197
+ raw.description === null
198
+ ? undefined
199
+ : (raw.description as string | undefined),
200
+ state: raw.state as string | undefined,
201
+ draft:
202
+ typeof raw.draft === "boolean"
203
+ ? raw.draft
204
+ : typeof raw.work_in_progress === "boolean"
205
+ ? raw.work_in_progress
206
+ : undefined,
207
+ webUrl: raw.web_url as string | undefined,
208
+ headSha:
209
+ (raw.sha as string | null | undefined) ??
210
+ (diffRefs?.head_sha as string | undefined),
211
+ sourceBranch: raw.source_branch as string | undefined,
212
+ targetBranch: raw.target_branch as string | undefined,
213
+ authorUsername: asRecord(raw.author)?.username as string | undefined,
214
+ baseSha: nonEmptyString(diffRefs?.base_sha),
215
+ changedFilesCount:
216
+ changesCount !== undefined && /^\d+$/.test(changesCount)
217
+ ? Number(changesCount)
218
+ : undefined,
219
+ };
220
+ },
221
+ async getMergeBaseSha(base, headSha) {
222
+ const data = await client.request<{ id?: string }>({
223
+ method: "GET",
224
+ path: `${projectPath}/repository/merge_base?refs[]=${encodeURIComponent(base)}&refs[]=${encodeURIComponent(headSha)}`,
225
+ });
226
+ return nonEmptyString(data.id);
227
+ },
228
+ async listMergeRequestDiffs(iid) {
229
+ const files: GitLabApiMergeRequestDiff[] = [];
230
+ for (let page = 1; ; page += 1) {
231
+ const diffs = await client.request<Record<string, unknown>[]>({
232
+ method: "GET",
233
+ path: `${projectPath}/merge_requests/${iid}/diffs`,
234
+ query: { page, per_page: GITLAB_DIFFS_PER_PAGE },
235
+ });
236
+ for (const diff of diffs) {
237
+ const status =
238
+ diff.new_file === true
239
+ ? "added"
240
+ : diff.deleted_file === true
241
+ ? "removed"
242
+ : diff.renamed_file === true
243
+ ? "renamed"
244
+ : "modified";
245
+ const rawPatch =
246
+ typeof diff.diff === "string" ? diff.diff : undefined;
247
+ files.push({
248
+ oldPath: diff.old_path as string,
249
+ newPath: diff.new_path as string,
250
+ status,
251
+ patch: rawPatch?.replace(/\n$/, ""),
252
+ });
253
+ }
254
+ if (diffs.length < GITLAB_DIFFS_PER_PAGE) {
255
+ return files;
256
+ }
257
+ }
258
+ },
259
+ };
260
+ }
261
+
139
262
  function buildQuery(query: GitLabRequestInput["query"]): string {
140
263
  if (query === undefined) {
141
264
  return "";
@@ -176,6 +176,18 @@ export function gitlabMergeRequestUrl(
176
176
  return explicit ?? `${project.webUrl}/-/merge_requests/${iid}`;
177
177
  }
178
178
 
179
+ /**
180
+ * Whether an `update` payload marks a draft merge request ready. GitLab uses
181
+ * either `changes.draft` or the legacy `changes.work_in_progress` shape.
182
+ */
183
+ export function gitlabDraftMarkedReady(
184
+ payload: Record<string, unknown>
185
+ ): boolean {
186
+ const changes = asRecord(payload.changes);
187
+ const draft = asRecord(changes?.draft ?? changes?.work_in_progress);
188
+ return draft?.current === false && draft.previous !== false;
189
+ }
190
+
179
191
  /** Normalize a merge-request record (`object_attributes` or `merge_request`). */
180
192
  export function gitlabMergeRequestFromRecord(
181
193
  project: GitLabProjectRef,
@@ -22,6 +22,7 @@ export * from "./api.js";
22
22
  export {
23
23
  buildGitLabBinding,
24
24
  type GitLabHandle,
25
+ gitlabDraftMarkedReady,
25
26
  gitlabMergeRequestFromRecord,
26
27
  gitlabMergeRequestUrl,
27
28
  gitlabProjectFromPayload,
@@ -99,13 +99,20 @@ function asBoolean(value: unknown): boolean | undefined {
99
99
  function originActor(value: unknown): OriginActor | undefined {
100
100
  const record = asRecord(value);
101
101
  if (record === undefined) return undefined;
102
- const nestedUser = asRecord(record.user);
103
- const nestedApp = asRecord(record.app);
104
- const id =
105
- asNonEmptyString(nestedUser?.id) ??
106
- asNonEmptyString(nestedApp?.id) ??
107
- asNonEmptyString(asRecord(record.serviceAccount)?.id) ??
108
- asNonEmptyString(record.id);
102
+
103
+ const nestedActors = [
104
+ ["user", asRecord(record.user)],
105
+ ["app", asRecord(record.app)],
106
+ ["service_account", asRecord(record.serviceAccount)],
107
+ ] as const;
108
+ for (const [kind, actor] of nestedActors) {
109
+ const id = asNonEmptyString(actor?.id);
110
+ if (id !== undefined) {
111
+ return { id, kind };
112
+ }
113
+ }
114
+
115
+ const id = asNonEmptyString(record.id);
109
116
  if (id === undefined) return undefined;
110
117
  const kind = asNonEmptyString(record.kind);
111
118
  return kind === undefined ? { id } : { id, kind };
@@ -361,16 +368,20 @@ export function defaultOriginAuth(
361
368
  ctx: Omit<OriginEventContext, "host" | "artifacts" | "origin">
362
369
  ): AuthContext {
363
370
  const senderId = ctx.sender?.id;
371
+ const senderKind = ctx.sender?.kind;
364
372
  return {
365
373
  authenticator: "origin-webhook",
366
374
  principalId: senderId ?? "origin",
367
- principalType: ctx.sender?.kind === "app" ? "service" : "user",
375
+ principalType:
376
+ senderKind === "app" || senderKind === "service_account"
377
+ ? "service"
378
+ : "user",
368
379
  attributes: {
369
380
  conversation_kind: "pull_request",
370
381
  repository: ctx.repository.fullName,
371
382
  ...(ctx.deliveryId === undefined ? {} : { delivery_id: ctx.deliveryId }),
372
383
  ...(senderId === undefined ? {} : { subject: senderId }),
373
- ...(ctx.sender?.kind === undefined ? {} : { user_type: ctx.sender.kind }),
384
+ ...(senderKind === undefined ? {} : { user_type: senderKind }),
374
385
  issuer: `origin:${ctx.repository.owner}`,
375
386
  },
376
387
  };
@@ -461,17 +472,19 @@ async function startTurn(input: {
461
472
  state: OriginChannelState;
462
473
  }): Promise<Response> {
463
474
  const source = continuationSource(input.options.continuation, "origin");
475
+ const cloud = input.dispatch.cloud ?? input.cloud;
476
+ const state = { ...input.dispatch.state, ...input.state };
464
477
  const session = await input.args.send(input.message, {
465
478
  auth: input.dispatch.auth,
466
479
  ...(source === "engine"
467
480
  ? { continuationToken: originContinuationKey(input.ctx) }
468
481
  : {}),
469
482
  title: input.dispatch.title ?? defaultOriginTitle(input.ctx),
470
- ...(input.cloud === undefined ? {} : { cloud: input.cloud }),
471
- state: input.state as unknown as JsonValue,
483
+ cloud,
484
+ state: state as unknown as JsonValue,
472
485
  // Resume must refresh the triggering comment / delivery identifiers so
473
486
  // reply delivery targets the latest wake, not the session's first.
474
- refreshState: input.state as unknown as JsonValue,
487
+ refreshState: state as unknown as JsonValue,
475
488
  });
476
489
  return turnStarted(session);
477
490
  }
@@ -605,7 +618,10 @@ export async function dispatchOriginWebhook(input: {
605
618
  ctx,
606
619
  dispatch,
607
620
  extra: { event: eventType },
608
- message: `Origin comment on ${ctx.repository.fullName}#${ctx.pullRequestNumber}`,
621
+ message:
622
+ commentBody.trim() === ""
623
+ ? `Origin comment on ${ctx.repository.fullName}#${ctx.pullRequestNumber}`
624
+ : commentBody.trim(),
609
625
  triggeringCommentId: commentId,
610
626
  });
611
627
  }
@@ -7,6 +7,7 @@ import type {
7
7
  ChannelEventHandlers,
8
8
  ChannelStartArgs,
9
9
  HostContext,
10
+ JsonObject,
10
11
  SendMessageFn,
11
12
  } from "../../types.js";
12
13
  import type { OriginTokenProvider } from "./api.js";
@@ -95,6 +96,10 @@ export type OriginTurnDispatch = {
95
96
  message?: string;
96
97
  title?: string;
97
98
  context?: readonly string[];
99
+ /** Per-turn cloud options. Overrides the channel-level `cloud` resolver. */
100
+ cloud?: AgentCloudOptions;
101
+ /** Extra durable channel state. Provider-owned fields take precedence. */
102
+ state?: JsonObject;
98
103
  };
99
104
 
100
105
  /** Bound per-delivery helpers passed to an {@link OriginTaskDispatch.task}. */
@@ -8,6 +8,7 @@ import {
8
8
  type MailboxContinuation,
9
9
  normalizeIdentity,
10
10
  } from "../../internal/continuation-identity.js";
11
+ import { isDeferredChannelSession } from "../../internal/deferred-channel-session.js";
11
12
  import { routeLocalIngressContinuation } from "../../internal/local-ingress.js";
12
13
  import { steeringEnabled } from "../../internal/steering.js";
13
14
  import type {
@@ -189,6 +190,14 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
189
190
  */
190
191
  suggestedPrompts?: SlackSuggestedPrompt[];
191
192
  suggestedPromptsTitle?: string;
193
+ /**
194
+ * Rethrow handler failures out of the dispatch promise instead of
195
+ * swallowing them after the error log. Hosted admission sets this so a
196
+ * throwing handler rejects `waitUntil` and surfaces as a retryable 503
197
+ * to the control plane (matching the GitHub/Origin adapters); the
198
+ * long-lived Socket Mode loop keeps the swallow-and-log default.
199
+ */
200
+ propagateHandlerErrors?: boolean;
192
201
  }
193
202
 
194
203
  function triggeringMergeMessage(
@@ -267,6 +276,8 @@ export async function dispatchInboundMessage(args: {
267
276
  followUpStatus?: boolean;
268
277
  blockExternals?: boolean;
269
278
  continuation?: ContinuationIdentity;
279
+ /** See {@link SlackInboundDispatchDeps.propagateHandlerErrors}. */
280
+ propagateHandlerErrors?: boolean;
270
281
  }): Promise<void> {
271
282
  const { message, kind } = args;
272
283
  const log = args.log ?? defaultSlackLog;
@@ -399,6 +410,9 @@ export async function dispatchInboundMessage(args: {
399
410
  thread_ts: message.threadTs,
400
411
  event_id: args.eventId,
401
412
  });
413
+ if (args.propagateHandlerErrors === true) {
414
+ throw error;
415
+ }
402
416
  return;
403
417
  }
404
418
  if (decision === null || decision === undefined) {
@@ -527,6 +541,19 @@ export async function dispatchInboundMessage(args: {
527
541
 
528
542
  try {
529
543
  const session = await args.send(prompt, sendOptions);
544
+ if (isDeferredChannelSession(session)) {
545
+ // Hosted admission captured the send; the control plane allocates
546
+ // the session and runs the turn only after this delivery is
547
+ // acknowledged, so there is nothing to observe or coalesce yet.
548
+ log.info("session send captured (hosted admission)", {
549
+ kind,
550
+ continuation,
551
+ channel: message.channelId,
552
+ thread_ts: message.threadTs,
553
+ event_id: args.eventId,
554
+ });
555
+ return;
556
+ }
530
557
  log.info(
531
558
  session.coalesced === true ? "session coalesced" : "session start",
532
559
  {
@@ -659,6 +686,7 @@ export function dispatchInboundFromEventBody(
659
686
  kind: "app_mention",
660
687
  message: mention,
661
688
  handler: deps.onAppMention,
689
+ propagateHandlerErrors: deps.propagateHandlerErrors,
662
690
  send: deps.send,
663
691
  credentials: deps.credentials,
664
692
  host: deps.host,
@@ -702,6 +730,7 @@ export function dispatchInboundFromEventBody(
702
730
  kind: "direct_message",
703
731
  message: dm,
704
732
  handler: deps.onDirectMessage,
733
+ propagateHandlerErrors: deps.propagateHandlerErrors,
705
734
  send: deps.send,
706
735
  credentials: deps.credentials,
707
736
  host: deps.host,
@@ -739,6 +768,7 @@ export function dispatchInboundFromEventBody(
739
768
  kind: "reaction_added",
740
769
  message: reaction,
741
770
  handler: deps.onReactionAdded,
771
+ propagateHandlerErrors: deps.propagateHandlerErrors,
742
772
  send: deps.send,
743
773
  credentials: deps.credentials,
744
774
  host: deps.host,
@@ -1,17 +1,29 @@
1
1
  /**
2
- * `slackChannel()` — platform channel pack for Slack (Socket Mode).
2
+ * `slackChannel()` — platform channel pack for Slack.
3
3
  *
4
- * Inbound events arrive over a WebSocket (`SLACK_APP_TOKEN`); no public
5
- * Request URL or Events HTTP route is required. When `toolApprovals`
6
- * is enabled, Approve/Deny buttons arrive as Socket Mode `interactive`
7
- * envelopes.
4
+ * Local / self-hosted transport is Socket Mode: inbound events arrive over
5
+ * a WebSocket (`SLACK_APP_TOKEN`); no public Request URL or Events HTTP
6
+ * route is required. When `toolApprovals` is enabled, Approve/Deny buttons
7
+ * arrive as Socket Mode `interactive` envelopes.
8
+ *
9
+ * Hosted v2 transport is the control plane's Events API ingest: the CP
10
+ * verifies the managed app's signature, fans out on the declared
11
+ * `slackEventTypes` (`app_mention`, `message`), and delivers the full
12
+ * `event_callback` body through hosted admission — the attached adapter
13
+ * routes it through the same inbound dispatch as Socket Mode. Without an
14
+ * app token the socket transport idles, so a hosted pod never needs one.
8
15
  */
9
16
 
10
17
  import { allowAll, defineChannel } from "../../channels.js";
18
+ import {
19
+ skipped,
20
+ withPropagatingBackgroundErrors,
21
+ } from "../../internal/channel-dispatch.js";
11
22
  import {
12
23
  continuationSource,
13
24
  normalizeIdentity,
14
25
  } from "../../internal/continuation-identity.js";
26
+ import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-adapter.js";
15
27
  import type {
16
28
  ArtifactsApi,
17
29
  ChannelDefinition,
@@ -51,7 +63,7 @@ import {
51
63
  emptySlackChannelState,
52
64
  type SlackInboundDispatchDeps,
53
65
  } from "./dispatch.js";
54
- import { createEventIdDedupe } from "./event-id-dedupe.js";
66
+ import { createEventIdDedupe, type EventIdDedupe } from "./event-id-dedupe.js";
55
67
  import {
56
68
  dispatchBlockAction,
57
69
  dispatchInteractiveFromPayload,
@@ -159,6 +171,18 @@ export function slackChannel(
159
171
  normalizeBotMentionAllowlist(botMentions.allowFrom);
160
172
  }
161
173
  const eventIds = createEventIdDedupe();
174
+ // Hosted v2 event capability, matching what the engagement flags can
175
+ // dispatch: mentions ride `app_mention`; DMs and watched channel posts
176
+ // both arrive as `message`. Membership of `slack.thread/v2` admits
177
+ // exactly these two, so `reaction_added` (hosted follow-up only inside
178
+ // an existing thread) is deliberately not declared.
179
+ const slackEventTypes: string[] = [];
180
+ if (mentionsEnabled) {
181
+ slackEventTypes.push("app_mention");
182
+ }
183
+ if (directMessagesEnabled || channelPosts !== undefined) {
184
+ slackEventTypes.push("message");
185
+ }
162
186
  const toolApprovals = options.toolApprovals === true;
163
187
  const interactivity = options.interactivity === true;
164
188
  const onBlockAction = options.onBlockAction;
@@ -201,6 +225,9 @@ export function slackChannel(
201
225
  waitUntil: (promise: Promise<unknown>) => void;
202
226
  host: HostContext;
203
227
  artifacts: ArtifactsApi;
228
+ /** Override the channel-level dedupe (hosted admission passes a fresh one). */
229
+ eventIds?: EventIdDedupe;
230
+ propagateHandlerErrors?: boolean;
204
231
  hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
205
232
  isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
206
233
  getContinuationLastBotMessageTs?: (
@@ -216,7 +243,8 @@ export function slackChannel(
216
243
  onDirectMessage,
217
244
  ...(onReactionAdded === undefined ? {} : { onReactionAdded }),
218
245
  credentials,
219
- eventIds,
246
+ eventIds: args.eventIds ?? eventIds,
247
+ propagateHandlerErrors: args.propagateHandlerErrors,
220
248
  host: args.host,
221
249
  artifacts: args.artifacts,
222
250
  log: getLog(),
@@ -253,6 +281,10 @@ export function slackChannel(
253
281
  routes: [],
254
282
  meta: {
255
283
  kind: "slack",
284
+ // Omitted (not empty) when nothing dispatches, so fanout never
285
+ // materializes a subscription with no event types.
286
+ slackEventTypes:
287
+ slackEventTypes.length === 0 ? undefined : slackEventTypes,
256
288
  ...(channelPosts === undefined
257
289
  ? {}
258
290
  : { slackChannelPosts: [...channelPosts.allow] }),
@@ -551,6 +583,36 @@ export function slackChannel(
551
583
  });
552
584
 
553
585
  slackChannelOptionsByDefinition.set(definition, options);
586
+ attachHostedAdmissionAdapter(definition, {
587
+ kind: "slack",
588
+ prepareArgs: withPropagatingBackgroundErrors,
589
+ // The payload is the full `event_callback` body the CP verified — the
590
+ // same shape Socket Mode unwraps — so it routes through the same
591
+ // inbound dispatch. Outcomes: a captured `send` overrides the fallback
592
+ // tag below, so `skipped` surfaces when the engagement rules declined
593
+ // (`not_engaged`) or no handler takes the shape (`not_dispatchable`);
594
+ // a throwing handler rejects `waitUntil` (propagateHandlerErrors) and
595
+ // hosted admission answers a retryable 503, like the PR adapters.
596
+ // The channel-level event_id dedupe is deliberately bypassed with a
597
+ // fresh instance per delivery: the control plane's app-scoped ingress
598
+ // claim already dedupes Slack retries, and on a warm pod the local set
599
+ // would otherwise swallow the control plane's own retry of a delivery
600
+ // that failed after the id was marked handled.
601
+ dispatch: async ({ payload, args }) => {
602
+ const dispatched = dispatchInboundFromEventBody(
603
+ payload,
604
+ inboundDeps({
605
+ send: args.send,
606
+ waitUntil: args.waitUntil,
607
+ host: args.host,
608
+ artifacts: args.artifacts,
609
+ eventIds: createEventIdDedupe(),
610
+ propagateHandlerErrors: true,
611
+ })
612
+ );
613
+ return skipped(dispatched ? "not_engaged" : "not_dispatchable");
614
+ },
615
+ });
554
616
 
555
617
  return definition;
556
618
  }
package/src/channels.ts CHANGED
@@ -64,9 +64,11 @@ export {
64
64
  } from "./channels/checks.js";
65
65
 
66
66
  import { Buffer } from "node:buffer";
67
- import { timingSafeEqual } from "node:crypto";
67
+ import { createHmac, timingSafeEqual } from "node:crypto";
68
68
  import { brandDefinition } from "./internal/brand.js";
69
69
  import { normalizeIdentity } from "./internal/continuation-identity.js";
70
+ import { attachCatchAdmission } from "./internal/hosted-catch.js";
71
+ import { attachHttpControlPlaneAdmission } from "./internal/http-control-plane-session.js";
70
72
  import { isLoopbackAddress, isLoopbackHostname } from "./internal/net.js";
71
73
  import type {
72
74
  AuthContext,
@@ -117,7 +119,16 @@ export type {
117
119
  export function defineChannel<TState = JsonValue>(
118
120
  config: ChannelConfig<TState>
119
121
  ): ChannelDefinition<TState> {
120
- return brandDefinition("channel", config);
122
+ const definition = brandDefinition("channel", config);
123
+ if (config.routes !== undefined && config.routes.length > 0) {
124
+ // Hosted: the control plane catches declared routes and replays them
125
+ // here. Provider packs attach their own admission afterwards.
126
+ attachCatchAdmission(
127
+ definition as ChannelDefinition<unknown>,
128
+ config.routes
129
+ );
130
+ }
131
+ return definition;
121
132
  }
122
133
 
123
134
  /**
@@ -127,13 +138,15 @@ export function defineChannel<TState = JsonValue>(
127
138
  export function httpChannel(
128
139
  config: HttpChannelConfig = {}
129
140
  ): HttpChannelDefinition {
130
- if (config.continuation !== undefined) {
131
- return brandDefinition("http-channel", {
132
- ...config,
133
- continuation: normalizeIdentity(config.continuation, "http"),
134
- });
135
- }
136
- return brandDefinition("http-channel", config);
141
+ const definition =
142
+ config.continuation !== undefined
143
+ ? brandDefinition("http-channel", {
144
+ ...config,
145
+ continuation: normalizeIdentity(config.continuation, "http"),
146
+ })
147
+ : brandDefinition("http-channel", config);
148
+ attachHttpControlPlaneAdmission(definition);
149
+ return definition;
137
150
  }
138
151
 
139
152
  // ============================================================================
@@ -432,7 +445,13 @@ export function publicEndpoint(): AuthPolicy {
432
445
  principalId: "anonymous",
433
446
  principalType: "user",
434
447
  });
435
- return Object.assign(policy, { [PUBLIC_ENDPOINT_MARKER]: true as const });
448
+ // On the v2 control plane this also makes the channel's routes catchable
449
+ // with handler-side verification (the v1 alias posture): the CP admits
450
+ // every request on a declared route and the handler rejects bad ones.
451
+ return markCatchAuth(
452
+ Object.assign(policy, { [PUBLIC_ENDPOINT_MARKER]: true as const }),
453
+ { kind: "public" }
454
+ );
436
455
  }
437
456
 
438
457
  /** True when a policy was created by {@link publicEndpoint}. */
@@ -443,3 +462,131 @@ export function isPublicEndpointPolicy(policy: AuthPolicy): boolean {
443
462
  ] === true
444
463
  );
445
464
  }
465
+
466
+ const CATCH_AUTH_MARKER = Symbol.for("agent-serve.catch-auth");
467
+
468
+ /**
469
+ * What `deploy` extracts from a {@link sharedSecretAuth} /
470
+ * {@link hmacSignatureAuth} policy into the manifest: the control plane runs
471
+ * the same check with the deployment secret of the same name before any
472
+ * compute starts. `secret` is a name, never a value.
473
+ */
474
+ export type CatchAuthDeclaration =
475
+ | { kind: "header"; header: string; secret: string }
476
+ | { kind: "hmac-sha256"; header: string; secret: string; prefix?: string }
477
+ /** `publicEndpoint()`: the handler verifies; the control plane only rate limits. */
478
+ | { kind: "public" };
479
+
480
+ function markCatchAuth(
481
+ policy: AuthPolicy,
482
+ declaration: CatchAuthDeclaration
483
+ ): AuthPolicy {
484
+ return Object.assign(policy, { [CATCH_AUTH_MARKER]: declaration });
485
+ }
486
+
487
+ /** The catch declaration a policy carries, if it is a catch-capable policy. */
488
+ export function catchAuthDeclaration(
489
+ policy: AuthPolicy
490
+ ): CatchAuthDeclaration | undefined {
491
+ const declaration = (policy as { [CATCH_AUTH_MARKER]?: unknown })[
492
+ CATCH_AUTH_MARKER
493
+ ];
494
+ return typeof declaration === "object" && declaration !== null
495
+ ? (declaration as CatchAuthDeclaration)
496
+ : undefined;
497
+ }
498
+
499
+ function presentedHeaderSecret(headerName: string, value: string): string {
500
+ if (
501
+ headerName === "authorization" &&
502
+ value.toLowerCase().startsWith("bearer ")
503
+ ) {
504
+ return value.slice("bearer ".length).trim();
505
+ }
506
+ return value.trim();
507
+ }
508
+
509
+ /**
510
+ * Admit requests whose `header` equals the secret named `secret` (an
511
+ * `Authorization: Bearer <secret>` header also matches). Locally the value
512
+ * is `process.env[secret]`; hosted, the deployment secret of that name. On
513
+ * Cursor hosting this ALSO declares the channel's routes reachable through
514
+ * the control-plane catch API, which runs the same comparison before any
515
+ * compute exists. An unset secret admits nothing.
516
+ */
517
+ export function sharedSecretAuth(options: {
518
+ header: string;
519
+ secret: string;
520
+ }): AuthPolicy {
521
+ const header = options.header.toLowerCase();
522
+ const policy: AuthPolicy = (request) => {
523
+ const expected = process.env[options.secret];
524
+ const presented = request.headers.get(header);
525
+ if (
526
+ expected === undefined ||
527
+ expected.length === 0 ||
528
+ presented === null ||
529
+ !constantTimeEquals(presentedHeaderSecret(header, presented), expected)
530
+ ) {
531
+ return null;
532
+ }
533
+ return {
534
+ authenticator: "shared-secret",
535
+ principalId: "webhook",
536
+ principalType: "service",
537
+ };
538
+ };
539
+ return markCatchAuth(policy, {
540
+ kind: "header",
541
+ header,
542
+ secret: options.secret,
543
+ });
544
+ }
545
+
546
+ /**
547
+ * Admit requests whose `header` carries the hex HMAC-SHA256 of the raw body
548
+ * under the secret named `secret` (optionally behind a literal `prefix`
549
+ * such as `sha256=`). Same local / hosted / catch semantics as
550
+ * {@link sharedSecretAuth}.
551
+ */
552
+ export function hmacSignatureAuth(options: {
553
+ header: string;
554
+ secret: string;
555
+ prefix?: string;
556
+ }): AuthPolicy {
557
+ const header = options.header.toLowerCase();
558
+ const prefix = options.prefix ?? "";
559
+ const policy: AuthPolicy = async (request) => {
560
+ const secret = process.env[options.secret];
561
+ const presented = request.headers.get(header)?.trim();
562
+ if (
563
+ secret === undefined ||
564
+ secret.length === 0 ||
565
+ presented === undefined ||
566
+ !presented.startsWith(prefix)
567
+ ) {
568
+ return null;
569
+ }
570
+ const body = Buffer.from(await request.clone().arrayBuffer());
571
+ const expected = createHmac("sha256", secret).update(body).digest("hex");
572
+ if (
573
+ !constantTimeEquals(
574
+ presented.slice(prefix.length).toLowerCase(),
575
+ expected
576
+ )
577
+ ) {
578
+ return null;
579
+ }
580
+ return {
581
+ authenticator: "hmac-signature",
582
+ principalId: "webhook",
583
+ principalType: "service",
584
+ };
585
+ };
586
+ return markCatchAuth(policy, {
587
+ kind: "hmac-sha256",
588
+ header,
589
+ secret: options.secret,
590
+ prefix: options.prefix,
591
+ });
592
+ }