@cursor/july 0.1.1 → 0.1.3

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 (298) hide show
  1. package/AGENTS.md +40 -7
  2. package/README.md +33 -24
  3. package/dist/bin/agent-serve.d.ts +3 -1
  4. package/dist/bin/agent-serve.d.ts.map +1 -1
  5. package/dist/bin/agent-serve.js +466 -140
  6. package/dist/channels/github/api.d.ts.map +1 -1
  7. package/dist/channels/github/api.js +31 -14
  8. package/dist/channels/github/cursor-account.d.ts +43 -0
  9. package/dist/channels/github/cursor-account.d.ts.map +1 -0
  10. package/dist/channels/github/cursor-account.js +95 -0
  11. package/dist/channels/github/github-channel.d.ts.map +1 -1
  12. package/dist/channels/github/github-channel.js +46 -9
  13. package/dist/channels/github/index.d.ts +2 -2
  14. package/dist/channels/github/index.js +2 -2
  15. package/dist/channels/github/types.d.ts +17 -0
  16. package/dist/channels/github/types.d.ts.map +1 -1
  17. package/dist/channels/slack/slack-channel.d.ts +8 -2
  18. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  19. package/dist/channels/slack/slack-channel.js +8 -0
  20. package/dist/channels/slack/types.d.ts +24 -3
  21. package/dist/channels/slack/types.d.ts.map +1 -1
  22. package/dist/channels/slack/types.js +15 -1
  23. package/dist/docs/404.html +2 -2
  24. package/dist/docs/ab.html +8 -8
  25. package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
  26. package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
  27. package/dist/docs/assets/{app.DqfFEmJd.js → app.BR0RbIdx.js} +1 -1
  28. package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
  29. package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
  30. package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.2Kg8jIp_.js} +2 -2
  31. package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
  32. package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
  33. package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
  34. package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
  35. package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
  36. package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
  37. package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
  38. package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
  39. package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
  40. package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
  41. package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
  42. package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
  43. package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
  44. package/dist/docs/assets/quickstart.md.BU6Iwi_9.js +204 -0
  45. package/dist/docs/assets/quickstart.md.BU6Iwi_9.lean.js +1 -0
  46. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
  47. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
  48. package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
  49. package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
  50. package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
  51. package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
  52. package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
  53. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
  54. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
  55. package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
  56. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
  57. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
  58. package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
  59. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
  60. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
  61. package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
  62. package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
  63. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
  64. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
  65. package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
  66. package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
  67. package/dist/docs/building-with-agents.html +4 -4
  68. package/dist/docs/concepts.html +4 -4
  69. package/dist/docs/deployment.html +7 -7
  70. package/dist/docs/evals.html +7 -7
  71. package/dist/docs/guides/agent-to-agent.html +6 -6
  72. package/dist/docs/guides/cloud-runtime.html +5 -5
  73. package/dist/docs/guides/github.html +14 -7
  74. package/dist/docs/guides/human-in-the-loop.html +6 -6
  75. package/dist/docs/guides/slack.html +8 -8
  76. package/dist/docs/guides/webhooks.html +6 -6
  77. package/dist/docs/hashmap.json +1 -1
  78. package/dist/docs/hillclimbing.html +5 -5
  79. package/dist/docs/index.html +7 -7
  80. package/dist/docs/quickstart.html +195 -26
  81. package/dist/docs/reference/agent-config.html +7 -7
  82. package/dist/docs/reference/channels.html +8 -8
  83. package/dist/docs/reference/cli.html +14 -9
  84. package/dist/docs/reference/connections.html +5 -5
  85. package/dist/docs/reference/hooks.html +5 -5
  86. package/dist/docs/reference/http-api.html +6 -6
  87. package/dist/docs/reference/instructions.html +13 -11
  88. package/dist/docs/reference/playground.html +4 -4
  89. package/dist/docs/reference/project-layout.html +4 -4
  90. package/dist/docs/reference/schedules.html +7 -7
  91. package/dist/docs/reference/sessions.html +4 -4
  92. package/dist/docs/reference/skills.html +6 -6
  93. package/dist/docs/reference/subagents.html +6 -6
  94. package/dist/docs/reference/tools.html +7 -7
  95. package/dist/docs/scaffolding-agents.html +5 -5
  96. package/dist/docs/storage.html +41 -0
  97. package/dist/docs/troubleshooting.html +4 -4
  98. package/dist/index.d.ts +2 -0
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +1 -0
  101. package/dist/internal/chat-client.d.ts +29 -3
  102. package/dist/internal/chat-client.d.ts.map +1 -1
  103. package/dist/internal/chat-client.js +180 -27
  104. package/dist/internal/cli-ax.d.ts +75 -2
  105. package/dist/internal/cli-ax.d.ts.map +1 -1
  106. package/dist/internal/cli-ax.js +600 -52
  107. package/dist/internal/cli-cursor.d.ts.map +1 -1
  108. package/dist/internal/cli-cursor.js +8 -36
  109. package/dist/internal/cli-deploy.d.ts +108 -0
  110. package/dist/internal/cli-deploy.d.ts.map +1 -0
  111. package/dist/internal/cli-deploy.js +1009 -0
  112. package/dist/internal/cursor/backend-client.d.ts +10 -1
  113. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  114. package/dist/internal/cursor/backend-client.js +79 -1
  115. package/dist/internal/cursor/credentials.d.ts +9 -0
  116. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  117. package/dist/internal/cursor/credentials.js +12 -0
  118. package/dist/internal/cursor/github-credentials.d.ts +44 -0
  119. package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
  120. package/dist/internal/cursor/github-credentials.js +195 -0
  121. package/dist/internal/deploy-client.d.ts +184 -0
  122. package/dist/internal/deploy-client.d.ts.map +1 -0
  123. package/dist/internal/deploy-client.js +395 -0
  124. package/dist/internal/deploy-source.d.ts +35 -0
  125. package/dist/internal/deploy-source.d.ts.map +1 -0
  126. package/dist/internal/deploy-source.js +118 -0
  127. package/dist/internal/discovery.d.ts +11 -0
  128. package/dist/internal/discovery.d.ts.map +1 -1
  129. package/dist/internal/discovery.js +116 -19
  130. package/dist/internal/distribution.d.ts.map +1 -1
  131. package/dist/internal/distribution.js +1 -0
  132. package/dist/internal/eval-run-store.d.ts +22 -3
  133. package/dist/internal/eval-run-store.d.ts.map +1 -1
  134. package/dist/internal/eval-run-store.js +39 -20
  135. package/dist/internal/eval-runner.d.ts +2 -0
  136. package/dist/internal/eval-runner.d.ts.map +1 -1
  137. package/dist/internal/eval-runner.js +2 -0
  138. package/dist/internal/event-mapper.d.ts +54 -1
  139. package/dist/internal/event-mapper.d.ts.map +1 -1
  140. package/dist/internal/event-mapper.js +151 -41
  141. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
  142. package/dist/internal/handleAgentServeTrigger.js +10 -12
  143. package/dist/internal/host-platforms.d.ts +7 -2
  144. package/dist/internal/host-platforms.d.ts.map +1 -1
  145. package/dist/internal/host-platforms.js +15 -10
  146. package/dist/internal/hosting.d.ts +37 -0
  147. package/dist/internal/hosting.d.ts.map +1 -0
  148. package/dist/internal/hosting.js +67 -0
  149. package/dist/internal/init-project.d.ts +88 -1
  150. package/dist/internal/init-project.d.ts.map +1 -1
  151. package/dist/internal/init-project.js +221 -31
  152. package/dist/internal/install-cursor-skills.d.ts +64 -0
  153. package/dist/internal/install-cursor-skills.d.ts.map +1 -0
  154. package/dist/internal/install-cursor-skills.js +274 -0
  155. package/dist/internal/logs-client.d.ts +60 -0
  156. package/dist/internal/logs-client.d.ts.map +1 -0
  157. package/dist/internal/logs-client.js +311 -0
  158. package/dist/internal/open-browser.d.ts +5 -0
  159. package/dist/internal/open-browser.d.ts.map +1 -0
  160. package/dist/internal/open-browser.js +34 -0
  161. package/dist/internal/playground/toolchain.d.ts.map +1 -1
  162. package/dist/internal/playground/toolchain.js +16 -11
  163. package/dist/internal/playground-proxy.d.ts +69 -0
  164. package/dist/internal/playground-proxy.d.ts.map +1 -0
  165. package/dist/internal/playground-proxy.js +468 -0
  166. package/dist/internal/prompt-context.d.ts +35 -0
  167. package/dist/internal/prompt-context.d.ts.map +1 -0
  168. package/dist/internal/prompt-context.js +71 -0
  169. package/dist/internal/reminder-runner.d.ts +7 -0
  170. package/dist/internal/reminder-runner.d.ts.map +1 -1
  171. package/dist/internal/reminder-runner.js +50 -6
  172. package/dist/internal/reminder-store.d.ts +2 -0
  173. package/dist/internal/reminder-store.d.ts.map +1 -1
  174. package/dist/internal/reminder-store.js +18 -0
  175. package/dist/internal/request-headers.d.ts +11 -0
  176. package/dist/internal/request-headers.d.ts.map +1 -0
  177. package/dist/internal/request-headers.js +14 -0
  178. package/dist/internal/resolve-prod-target.d.ts +42 -0
  179. package/dist/internal/resolve-prod-target.d.ts.map +1 -0
  180. package/dist/internal/resolve-prod-target.js +111 -0
  181. package/dist/internal/run-client.d.ts +2 -2
  182. package/dist/internal/run-client.d.ts.map +1 -1
  183. package/dist/internal/run-client.js +38 -23
  184. package/dist/internal/server.d.ts.map +1 -1
  185. package/dist/internal/server.js +182 -45
  186. package/dist/internal/session-engine.d.ts +50 -1
  187. package/dist/internal/session-engine.d.ts.map +1 -1
  188. package/dist/internal/session-engine.js +267 -23
  189. package/dist/internal/sessions-client.d.ts +21 -0
  190. package/dist/internal/sessions-client.d.ts.map +1 -0
  191. package/dist/internal/sessions-client.js +168 -0
  192. package/dist/internal/storage-coordinator.d.ts +139 -0
  193. package/dist/internal/storage-coordinator.d.ts.map +1 -0
  194. package/dist/internal/storage-coordinator.js +499 -0
  195. package/dist/internal/stream-progress.d.ts.map +1 -1
  196. package/dist/internal/stream-progress.js +31 -3
  197. package/dist/internal/terminal-style.d.ts +22 -0
  198. package/dist/internal/terminal-style.d.ts.map +1 -0
  199. package/dist/internal/terminal-style.js +49 -0
  200. package/dist/internal/trajectory.d.ts +10 -5
  201. package/dist/internal/trajectory.d.ts.map +1 -1
  202. package/dist/internal/trajectory.js +82 -10
  203. package/dist/internal/workspace.d.ts +11 -0
  204. package/dist/internal/workspace.d.ts.map +1 -1
  205. package/dist/internal/workspace.js +38 -4
  206. package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
  207. package/dist/playground/assets/index-D-vo2lV_.css +1 -0
  208. package/dist/playground/assets/index-x60b9q2j.js +312 -0
  209. package/dist/playground/index.html +2 -2
  210. package/dist/storage.d.ts +204 -0
  211. package/dist/storage.d.ts.map +1 -0
  212. package/dist/storage.js +153 -0
  213. package/dist/types.d.ts +70 -4
  214. package/dist/types.d.ts.map +1 -1
  215. package/docs/README.md +3 -2
  216. package/docs/guides/github.md +43 -8
  217. package/docs/guides/slack.md +1 -1
  218. package/docs/quickstart.md +350 -57
  219. package/docs/reference/cli.md +51 -3
  220. package/docs/reference/instructions.md +8 -6
  221. package/docs/scaffolding-agents.md +1 -1
  222. package/docs/storage.md +98 -0
  223. package/package.json +10 -1
  224. package/skills/ab/SKILL.md +8 -8
  225. package/skills/create-agent/SKILL.md +28 -22
  226. package/skills/debug/SKILL.md +11 -11
  227. package/skills/evals/SKILL.md +16 -16
  228. package/skills/framework-map/SKILL.md +6 -6
  229. package/skills/github/SKILL.md +22 -14
  230. package/skills/hillclimb/SKILL.md +10 -10
  231. package/skills/setup-slack/SKILL.md +13 -13
  232. package/src/bin/agent-serve.ts +552 -179
  233. package/src/channels/github/api.ts +42 -23
  234. package/src/channels/github/cursor-account.ts +165 -0
  235. package/src/channels/github/github-channel.ts +66 -6
  236. package/src/channels/github/index.ts +2 -2
  237. package/src/channels/github/types.ts +19 -0
  238. package/src/channels/slack/slack-channel.ts +17 -3
  239. package/src/channels/slack/types.ts +44 -3
  240. package/src/index.ts +13 -0
  241. package/src/internal/chat-client.ts +252 -37
  242. package/src/internal/cli-ax.ts +722 -72
  243. package/src/internal/cli-cursor.ts +14 -42
  244. package/src/internal/cli-deploy.ts +1319 -0
  245. package/src/internal/cursor/backend-client.ts +103 -1
  246. package/src/internal/cursor/credentials.ts +14 -0
  247. package/src/internal/cursor/github-credentials.ts +248 -0
  248. package/src/internal/deploy-client.ts +632 -0
  249. package/src/internal/deploy-source.ts +133 -0
  250. package/src/internal/discovery.ts +141 -17
  251. package/src/internal/distribution.ts +1 -0
  252. package/src/internal/eval-run-store.ts +50 -20
  253. package/src/internal/eval-runner.ts +5 -0
  254. package/src/internal/event-mapper.ts +222 -42
  255. package/src/internal/handleAgentServeTrigger.ts +10 -12
  256. package/src/internal/host-platforms.ts +28 -11
  257. package/src/internal/hosting.ts +77 -0
  258. package/src/internal/init-project.ts +333 -51
  259. package/src/internal/install-cursor-skills.ts +327 -0
  260. package/src/internal/logs-client.ts +442 -0
  261. package/src/internal/open-browser.ts +41 -0
  262. package/src/internal/playground/toolchain.ts +15 -13
  263. package/src/internal/playground-proxy.ts +576 -0
  264. package/src/internal/prompt-context.ts +95 -0
  265. package/src/internal/reminder-runner.ts +50 -6
  266. package/src/internal/reminder-store.ts +21 -0
  267. package/src/internal/request-headers.ts +23 -0
  268. package/src/internal/resolve-prod-target.ts +150 -0
  269. package/src/internal/run-client.ts +39 -36
  270. package/src/internal/server.ts +223 -28
  271. package/src/internal/session-engine.ts +307 -10
  272. package/src/internal/sessions-client.ts +182 -0
  273. package/src/internal/storage-coordinator.ts +615 -0
  274. package/src/internal/stream-progress.ts +36 -2
  275. package/src/internal/terminal-style.ts +74 -0
  276. package/src/internal/trajectory.ts +91 -13
  277. package/src/internal/workspace.ts +42 -4
  278. package/src/storage.ts +325 -0
  279. package/src/types.ts +82 -8
  280. package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
  281. package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
  282. package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
  283. package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
  284. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
  285. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
  286. package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
  287. package/dist/playground/assets/index-1K-hG-7p.css +0 -1
  288. package/dist/playground/assets/index-FlWjhg3x.js +0 -79
  289. /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
  290. /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
  291. /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
  292. /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
  293. /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
  294. /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
  295. /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
  296. /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
  297. /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
  298. /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
@@ -14,12 +14,21 @@ import {
14
14
  } from "node:http";
15
15
  import type { AddressInfo } from "node:net";
16
16
  import { join } from "node:path";
17
+ import {
18
+ type CursorGithubRepoScope,
19
+ createCursorAccountGithubTokenResolver,
20
+ type GithubCursorAccountRuntime,
21
+ getGithubCursorAccountRuntime,
22
+ parseCursorGithubRepoScope,
23
+ resolveCursorGithubPermissions,
24
+ } from "../channels/github/cursor-account.js";
17
25
  import { findGitHubChannelTargets } from "../channels/github/forward.js";
18
26
  import {
19
27
  dispatchCursorSlackEnvelope,
20
28
  getSlackCursorAccountRuntime,
21
29
  type SlackCursorAccountRuntime,
22
30
  } from "../channels/slack/cursor-account.js";
31
+ import { assertSlackCursorAgentName } from "../channels/slack/types.js";
23
32
  import { allowAll, bearerAuth, localDevStrict } from "../channels.js";
24
33
  import type {
25
34
  AgentProject,
@@ -41,10 +50,12 @@ import {
41
50
  import { CursorBackendClient } from "./cursor/backend-client.js";
42
51
  import {
43
52
  cursorBackendUrl,
53
+ cursorExternalApiUrl,
44
54
  type ResolvedApiKey,
45
55
  resolveApiKey,
46
56
  SIGN_IN_HINT,
47
57
  } from "./cursor/credentials.js";
58
+ import { CursorGithubCredentialProvider } from "./cursor/github-credentials.js";
48
59
  import {
49
60
  CursorEventRelay,
50
61
  formatCursorScmEventLog,
@@ -76,7 +87,7 @@ import {
76
87
  collectGitHubTriggerTargets,
77
88
  handleAgentServeTrigger,
78
89
  } from "./handleAgentServeTrigger.js";
79
- import { warmupHostGitHubAuth } from "./host-platforms.js";
90
+ import { createHostPlatforms, warmupHostGitHubAuth } from "./host-platforms.js";
80
91
  import {
81
92
  buildHttpChannelRoutes,
82
93
  errorResponse,
@@ -187,9 +198,16 @@ export async function startServer(
187
198
  // agentkit_enabled gate applies to every turn.
188
199
  process.env.CURSOR_AGENTKIT_VERSION ??= packageVersion();
189
200
 
201
+ const cursorGithubTargets = collectCursorGithubTargets(mounts);
202
+ const cursorGithubConfig = resolveCursorGithubEventConfig({
203
+ configured: options.cursorEvents,
204
+ targets: cursorGithubTargets,
205
+ });
206
+ const effectiveCursorEvents = cursorGithubConfig.cursorEvents;
207
+
190
208
  // One resolution for every Cursor credential consumer (SDK runner, account
191
- // MCP bridge, SCM event relay): explicit option → CURSOR_API_KEY → stored
192
- // `agent-serve login`.
209
+ // MCP bridge, SCM event relay, GitHub credentials): explicit option →
210
+ // CURSOR_API_KEY → stored `agent-serve login`.
193
211
  const accountKey = await resolveApiKey(
194
212
  options.apiKey === undefined ? {} : { apiKey: options.apiKey }
195
213
  );
@@ -198,9 +216,58 @@ export async function startServer(
198
216
  // `cursorEvents` cannot work signed out. Require the credential before any
199
217
  // slow or stateful startup work (playground build, channel onStart, cron).
200
218
  const cursorEventsAuth =
201
- options.cursorEvents === undefined
219
+ effectiveCursorEvents === undefined
202
220
  ? undefined
203
- : requireCursorEventsAuth(options.cursorEvents, accountKey);
221
+ : requireCursorEventsAuth(effectiveCursorEvents, accountKey);
222
+
223
+ let cursorGithubCredentials: CursorGithubCredentialProvider | undefined;
224
+ if (cursorGithubConfig.scope !== undefined) {
225
+ if (cursorEventsAuth === undefined) {
226
+ throw new Error(
227
+ "githubChannel({ cursorAccount: true }) could not resolve Cursor event authentication."
228
+ );
229
+ }
230
+ if (options.allowAnonymous === true) {
231
+ if (options.allowAnonymousCursorGithub !== true) {
232
+ throw new Error(
233
+ "githubChannel({ cursorAccount: true }) cannot be served with --allow-anonymous because admitted callers could use the signed-in account's GitHub access. If every admitted caller is trusted (e.g. behind an SSO proxy), opt in with --allow-anonymous-cursor-github."
234
+ );
235
+ }
236
+ logger(
237
+ "[agent-serve] warning: --allow-anonymous-cursor-github — every admitted HTTP caller can drive sessions holding the signed-in account's repo-scoped GitHub credential; serve this only behind a trusted boundary (e.g. an SSO proxy)"
238
+ );
239
+ }
240
+ if (cursorGithubConfig.scope.permissions === "contents-write") {
241
+ logger(
242
+ '[agent-serve] warning: Cursor GitHub credentials include contents:write — the host holds a push-capable token shared with model-driven tools and untrusted webhook content; prefer permissions: "pr-write" unless this agent must push code'
243
+ );
244
+ }
245
+ const provider = new CursorGithubCredentialProvider({
246
+ client: new CursorBackendClient({
247
+ backendUrl: cursorEventsAuth.baseUrl,
248
+ apiKey: cursorEventsAuth.apiKey,
249
+ logger,
250
+ }),
251
+ scope: cursorGithubConfig.scope,
252
+ logger,
253
+ });
254
+ cursorGithubCredentials = provider;
255
+ for (const target of cursorGithubTargets) {
256
+ target.accountRuntime.credentials.bind(() => provider.getToken());
257
+ }
258
+ }
259
+ const resolvedCursorGithubCredentials = cursorGithubCredentials;
260
+ const hostPlatforms = createHostPlatforms(
261
+ resolvedCursorGithubCredentials === undefined
262
+ ? {}
263
+ : {
264
+ githubCredentials: {
265
+ token: createCursorAccountGithubTokenResolver(() =>
266
+ resolvedCursorGithubCredentials.getToken()
267
+ ),
268
+ },
269
+ }
270
+ );
204
271
 
205
272
  if (playground) {
206
273
  // Auto-build dist/playground when missing (monorepo / source checkout).
@@ -267,16 +334,42 @@ export async function startServer(
267
334
  const baseStateRoot =
268
335
  options.stateRoot ?? join(project.rootDir, ".agent-serve");
269
336
  const stateRoot = slug === "" ? baseStateRoot : join(baseStateRoot, slug);
270
- const engine = new SessionEngine({ project, stateRoot, runner, logger });
337
+ const engine = new SessionEngine({
338
+ project,
339
+ stateRoot,
340
+ runner,
341
+ logger,
342
+ platforms: hostPlatforms,
343
+ });
344
+ // Rehydrate sessions from the authored storage sink before any
345
+ // channel or route can address them (continuation tokens must resolve).
346
+ await engine.restoreStoredSessions();
347
+
271
348
  if (!githubAuthWarmed) {
272
349
  // Soft ambient GitHub auth check before channel onStart (which may call
273
350
  // host.github). Missing auth is a warning only — serve still starts.
274
- await warmupHostGitHubAuth({ logger, github: engine.host.github });
351
+ await warmupHostGitHubAuth({
352
+ logger,
353
+ github: engine.host.github,
354
+ ...(cursorGithubCredentials === undefined
355
+ ? {}
356
+ : { authSource: "cursor-account" }),
357
+ });
275
358
  githubAuthWarmed = true;
276
359
  }
277
360
  const scheduleRunner = new ScheduleRunner(engine, project, logger);
278
361
  const reminderRunner = new ReminderRunner(engine, logger);
279
- const evalRuns = new EvalRunStore(project.rootDir, logger);
362
+ const evalRuns = new EvalRunStore(
363
+ project.rootDir,
364
+ logger,
365
+ // defineStorage fallback for playground eval history; explicit
366
+ // `evals.config.ts` persistRuns still wins inside the store.
367
+ engine.storage?.asEvalRunPersistence()
368
+ );
369
+ // Eval history restores with the same startup step as sessions (reads
370
+ // also hydrate lazily, but doing it here surfaces store problems at
371
+ // boot and makes /v1/dev/evals complete from the first request).
372
+ await evalRuns.hydrate();
280
373
  engine.setReminders({
281
374
  create: (input) => reminderRunner.create(input),
282
375
  list: (filter) => reminderRunner.list(filter),
@@ -486,15 +579,6 @@ export async function startServer(
486
579
  });
487
580
  }
488
581
 
489
- // Cursor SCM events relay (opt-in: serve({ cursorEvents }) / --cursor-events).
490
- const cursorEventRelay = startCursorEventRelay({
491
- options,
492
- mounts,
493
- auth: cursorEventsAuth,
494
- logger,
495
- collectTriggerTargets,
496
- });
497
-
498
582
  // Cursor Slack relay: automatic when a mounted agent authored
499
583
  // `slackChannel({ cursorAccount: true })`. Inbound rides the account's
500
584
  // Slack connection (`/v0/slack-events`); the classic Socket-Mode path is
@@ -505,6 +589,24 @@ export async function startServer(
505
589
  accountKey,
506
590
  logger,
507
591
  });
592
+ try {
593
+ await cursorGithubCredentials?.start();
594
+ } catch (error) {
595
+ await cursorSlackRelay?.stop();
596
+ throw error;
597
+ }
598
+
599
+ // Cursor SCM events relay (opt-in: serve({ cursorEvents }) / --cursor-events).
600
+ const cursorEventRelay = startCursorEventRelay({
601
+ config: effectiveCursorEvents,
602
+ stateRoot: options.stateRoot,
603
+ mounts,
604
+ auth: cursorEventsAuth,
605
+ logger,
606
+ collectTriggerTargets,
607
+ cursorAccountOnly:
608
+ options.cursorEvents === undefined && cursorGithubTargets.length > 0,
609
+ });
508
610
 
509
611
  const server = createServer((req, res) => {
510
612
  void handleRequest(router, req, res, logger);
@@ -512,8 +614,15 @@ export async function startServer(
512
614
 
513
615
  const host = options.host ?? "127.0.0.1";
514
616
  const port = options.port ?? 3000;
515
- server.listen(port, host);
516
- await once(server, "listening");
617
+ try {
618
+ server.listen(port, host);
619
+ await once(server, "listening");
620
+ } catch (error) {
621
+ await cursorEventRelay?.stop();
622
+ await cursorSlackRelay?.stop();
623
+ cursorGithubCredentials?.stop();
624
+ throw error;
625
+ }
517
626
  const address = server.address() as AddressInfo;
518
627
  const displayHost = host === "0.0.0.0" || host === "::" ? "127.0.0.1" : host;
519
628
  const url = `http://${displayHost}:${address.port}`;
@@ -645,7 +754,11 @@ export async function startServer(
645
754
  }
646
755
  server.close();
647
756
  server.closeAllConnections();
648
- await Promise.all(runtimes.map((runtime) => runtime.engine.close()));
757
+ try {
758
+ await Promise.all(runtimes.map((runtime) => runtime.engine.close()));
759
+ } finally {
760
+ cursorGithubCredentials?.stop();
761
+ }
649
762
  },
650
763
  };
651
764
  if (playgroundDev?.url !== undefined) {
@@ -1223,7 +1336,10 @@ function requireCursorEventsAuth(
1223
1336
  }
1224
1337
  return {
1225
1338
  apiKey,
1226
- baseUrl: config.baseUrl ?? accountKey?.backendUrl ?? cursorBackendUrl(),
1339
+ // `/v0/scm-events/*` lives on the external API (api.cursor.com), not
1340
+ // api2. Prefer that default over the account key's backendUrl, which
1341
+ // follows cursorBackendUrl() (api2) when CURSOR_API_KEY is set.
1342
+ baseUrl: config.baseUrl ?? cursorExternalApiUrl(),
1227
1343
  };
1228
1344
  }
1229
1345
 
@@ -1233,14 +1349,16 @@ function requireCursorEventsAuth(
1233
1349
  * no github channel) warn and leave the relay off — serve still starts.
1234
1350
  */
1235
1351
  function startCursorEventRelay(input: {
1236
- options: ServeOptions;
1352
+ config: ServeOptions["cursorEvents"];
1353
+ stateRoot: string | undefined;
1237
1354
  mounts: AgentMount[];
1238
1355
  auth: CursorEventsAuth | undefined;
1239
1356
  logger: (line: string) => void;
1240
1357
  collectTriggerTargets: () => ReturnType<typeof collectGitHubTriggerTargets>;
1358
+ cursorAccountOnly: boolean;
1241
1359
  }): CursorEventRelay | undefined {
1242
- const { options, mounts, auth, logger, collectTriggerTargets } = input;
1243
- const config = options.cursorEvents;
1360
+ const { config, stateRoot, mounts, auth, logger, collectTriggerTargets } =
1361
+ input;
1244
1362
  if (config === undefined || auth === undefined) {
1245
1363
  return undefined;
1246
1364
  }
@@ -1262,7 +1380,7 @@ function startCursorEventRelay(input: {
1262
1380
  return undefined;
1263
1381
  }
1264
1382
  const baseStateRoot =
1265
- options.stateRoot ??
1383
+ stateRoot ??
1266
1384
  join(mounts[0]?.project.rootDir ?? process.cwd(), ".agent-serve");
1267
1385
  const relay = new CursorEventRelay({
1268
1386
  baseUrl: auth.baseUrl,
@@ -1275,12 +1393,27 @@ function startCursorEventRelay(input: {
1275
1393
  // envelope — rich pullRequest meta when present for onPullRequest Zod.
1276
1394
  dispatch: async (event) => {
1277
1395
  if (event.provider !== "github") return;
1396
+ const targets = collectTriggerTargets().filter((target) => {
1397
+ const cursorAccount = target.options.cursorAccount;
1398
+ if (
1399
+ input.cursorAccountOnly &&
1400
+ cursorAccount !== true &&
1401
+ typeof cursorAccount !== "object"
1402
+ ) {
1403
+ return false;
1404
+ }
1405
+ return typeof cursorAccount !== "object"
1406
+ ? true
1407
+ : cursorAccount.repos.some(
1408
+ (repo) => repo.toLowerCase() === event.repo.toLowerCase()
1409
+ );
1410
+ });
1278
1411
  const result = await handleAgentServeTrigger({
1279
1412
  type: "github",
1280
1413
  bodyText: JSON.stringify(scmMetadataToGitHubPayload(event)),
1281
1414
  eventName: event.eventName,
1282
1415
  deliveryId: event.deliveryId,
1283
- targets: collectTriggerTargets(),
1416
+ targets,
1284
1417
  });
1285
1418
  const outcomes = result.targets
1286
1419
  .map((target) => `${target.slug || "default"}:${target.status}`)
@@ -1297,6 +1430,64 @@ function startCursorEventRelay(input: {
1297
1430
  return relay;
1298
1431
  }
1299
1432
 
1433
+ interface CursorGithubTarget {
1434
+ slug: string;
1435
+ channelId: string;
1436
+ accountRuntime: GithubCursorAccountRuntime;
1437
+ }
1438
+
1439
+ function collectCursorGithubTargets(
1440
+ mounts: AgentMount[]
1441
+ ): CursorGithubTarget[] {
1442
+ const targets: CursorGithubTarget[] = [];
1443
+ for (const mount of mounts) {
1444
+ for (const channel of mount.project.channels) {
1445
+ const accountRuntime = getGithubCursorAccountRuntime(channel.definition);
1446
+ if (accountRuntime !== undefined) {
1447
+ targets.push({
1448
+ slug: mount.slug,
1449
+ channelId: channel.id,
1450
+ accountRuntime,
1451
+ });
1452
+ }
1453
+ }
1454
+ }
1455
+ return targets;
1456
+ }
1457
+
1458
+ interface CursorGithubConfigResolution {
1459
+ cursorEvents: ServeOptions["cursorEvents"];
1460
+ scope: CursorGithubRepoScope | undefined;
1461
+ }
1462
+
1463
+ function resolveCursorGithubEventConfig(input: {
1464
+ configured: ServeOptions["cursorEvents"];
1465
+ targets: CursorGithubTarget[];
1466
+ }): CursorGithubConfigResolution {
1467
+ if (input.targets.length === 0) {
1468
+ return { cursorEvents: input.configured, scope: undefined };
1469
+ }
1470
+ const repos = [
1471
+ ...(input.configured?.repos ?? []),
1472
+ ...input.targets.flatMap((target) => [
1473
+ ...(target.accountRuntime.scope?.repos ?? []),
1474
+ ]),
1475
+ ];
1476
+ const permissions = resolveCursorGithubPermissions(
1477
+ input.targets.map(
1478
+ (target) => target.accountRuntime.scope?.permissions ?? "pr-write"
1479
+ )
1480
+ );
1481
+ const scope = parseCursorGithubRepoScope(repos, permissions);
1482
+ return {
1483
+ cursorEvents: {
1484
+ ...input.configured,
1485
+ repos: [...scope.repos],
1486
+ },
1487
+ scope,
1488
+ };
1489
+ }
1490
+
1300
1491
  interface CursorSlackTarget {
1301
1492
  runtime: MountedRuntime;
1302
1493
  channelId: string;
@@ -1304,13 +1495,16 @@ interface CursorSlackTarget {
1304
1495
  accountRuntime: SlackCursorAccountRuntime;
1305
1496
  }
1306
1497
 
1307
- /** `weather-agent` → `Weather Agent` (Slack display name default). */
1498
+ /**
1499
+ * `weather-agent` → `WeatherAgent` (single-token Cursor Slack handle).
1500
+ * Must not contain whitespace — see {@link assertSlackCursorAgentName}.
1501
+ */
1308
1502
  function slackAgentNameFromSlug(slug: string): string {
1309
1503
  return slug
1310
1504
  .split(/[-_\s]+/)
1311
1505
  .filter((word) => word.length > 0)
1312
1506
  .map((word) => word[0].toUpperCase() + word.slice(1))
1313
- .join(" ");
1507
+ .join("");
1314
1508
  }
1315
1509
 
1316
1510
  /**
@@ -1341,6 +1535,7 @@ function collectCursorSlackTargets(
1341
1535
  `slackChannel({ cursorAccount: true }) on agent "${runtime.slug || runtime.project.name}" resolved an empty agent name; set agentName.`
1342
1536
  );
1343
1537
  }
1538
+ assertSlackCursorAgentName(agentName);
1344
1539
  const nameKey = agentName.toLowerCase();
1345
1540
  const existing = byName.get(nameKey);
1346
1541
  if (existing !== undefined) {