@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
@@ -4,11 +4,63 @@
4
4
  * (`SessionEvent` payloads). One mapper instance covers one turn.
5
5
  */
6
6
 
7
- import type { InteractionUpdate, ToolCall } from "@cursor/sdk";
7
+ import type {
8
+ InteractionUpdate as SdkInteractionUpdate,
9
+ ToolCall,
10
+ } from "@cursor/sdk";
8
11
  import type { SessionEventPayload, TurnUsage } from "../types.js";
9
12
 
10
13
  const CUSTOM_TOOLS_PROVIDER = "custom-user-tools";
11
14
 
15
+ /**
16
+ * Nested interaction updates from a task/subagent tool-call-delta.
17
+ * Mirrored locally so agent-serve typechecks against published `@cursor/sdk`
18
+ * versions that do not yet export `NestedTaskUpdate` / `tool-call-delta`.
19
+ */
20
+ type NestedTaskUpdate =
21
+ | { type: "text-delta"; text: string }
22
+ | { type: "thinking-delta"; text: string }
23
+ | { type: "thinking-completed"; thinkingDurationMs: number }
24
+ | {
25
+ type: "tool-call-started";
26
+ callId: string;
27
+ toolCall: ToolCall;
28
+ modelCallId: string;
29
+ }
30
+ | {
31
+ type: "tool-call-completed";
32
+ callId: string;
33
+ toolCall: ToolCall;
34
+ modelCallId: string;
35
+ }
36
+ | {
37
+ type: "partial-tool-call";
38
+ callId: string;
39
+ toolCall: ToolCall;
40
+ modelCallId: string;
41
+ }
42
+ | { type: "step-started"; stepId: number }
43
+ | { type: "step-completed"; stepId: number; stepDurationMs: number };
44
+
45
+ type ToolCallDeltaUpdate = {
46
+ type: "tool-call-delta";
47
+ callId: string;
48
+ modelCallId: string;
49
+ taskUpdate: NestedTaskUpdate;
50
+ };
51
+
52
+ /** SDK updates plus nested task deltas once the SDK exposes them. */
53
+ type InteractionUpdate = SdkInteractionUpdate | ToolCallDeltaUpdate;
54
+
55
+ function asToolCallDelta(
56
+ update: InteractionUpdate
57
+ ): ToolCallDeltaUpdate | undefined {
58
+ if ((update as { type: string }).type !== "tool-call-delta") {
59
+ return undefined;
60
+ }
61
+ return update as ToolCallDeltaUpdate;
62
+ }
63
+
12
64
  export interface ToolCallDescription {
13
65
  toolName: string;
14
66
  args?: unknown;
@@ -20,12 +72,19 @@ export interface ToolResultDescription {
20
72
  isError: boolean;
21
73
  }
22
74
 
75
+ interface NestedAccumulators {
76
+ text: string;
77
+ reasoning: string;
78
+ }
79
+
23
80
  export class TurnEventMapper {
24
81
  private textAccumulator = "";
25
82
  private reasoningAccumulator = "";
26
83
  private usageTotal: TurnUsage | undefined;
27
84
  private lastAssistantText: string | undefined;
28
85
  private summaryTitle: string | undefined;
86
+ /** Per-parent-call accumulators for nested subagent streams. */
87
+ private readonly nested = new Map<string, NestedAccumulators>();
29
88
 
30
89
  constructor(private readonly emit: (payload: SessionEventPayload) => void) {}
31
90
 
@@ -74,49 +133,11 @@ export class TurnEventMapper {
74
133
  }
75
134
  case "tool-call-started": {
76
135
  this.flushAssistantText("tool_call");
77
- const description = describeToolCall(update.toolCall);
78
- this.emit({
79
- type: "actions.requested",
80
- data: {
81
- calls: [
82
- {
83
- callId: update.callId,
84
- toolName: description.toolName,
85
- args: description.args,
86
- },
87
- ],
88
- },
89
- });
90
- if (description.subagent !== undefined) {
91
- this.emit({
92
- type: "subagent.called",
93
- data: {
94
- callId: update.callId,
95
- name: description.subagent.name,
96
- description: description.subagent.description,
97
- },
98
- });
99
- }
136
+ this.emitToolStarted(update.callId, update.toolCall);
100
137
  return;
101
138
  }
102
139
  case "tool-call-completed": {
103
- const description = describeToolCall(update.toolCall);
104
- const result = describeToolResult(update.toolCall);
105
- this.emit({
106
- type: "action.result",
107
- data: {
108
- callId: update.callId,
109
- toolName: description.toolName,
110
- output: result.output,
111
- isError: result.isError,
112
- },
113
- });
114
- if (description.subagent !== undefined) {
115
- this.emit({
116
- type: "subagent.completed",
117
- data: { callId: update.callId, name: description.subagent.name },
118
- });
119
- }
140
+ this.emitToolCompleted(update.callId, update.toolCall);
120
141
  return;
121
142
  }
122
143
  case "step-started": {
@@ -148,7 +169,13 @@ export class TurnEventMapper {
148
169
  case "shell-output-delta":
149
170
  return;
150
171
  default: {
151
- // Future harness update types are ignored rather than fatal.
172
+ // Nested task/subagent progress (tool-call-delta) accepted via
173
+ // structural check so we typecheck against older published SDKs.
174
+ const delta = asToolCallDelta(update);
175
+ if (delta !== undefined) {
176
+ this.handleNestedTaskUpdate(delta.callId, delta.taskUpdate);
177
+ return;
178
+ }
152
179
  return;
153
180
  }
154
181
  }
@@ -157,6 +184,143 @@ export class TurnEventMapper {
157
184
  /** Close out the turn: finalize any open assistant text block. */
158
185
  finish(): void {
159
186
  this.flushAssistantText("stop");
187
+ for (const parentCallId of this.nested.keys()) {
188
+ this.flushNestedAssistantText(parentCallId, "stop");
189
+ }
190
+ }
191
+
192
+ private handleNestedTaskUpdate(
193
+ parentCallId: string,
194
+ update: NestedTaskUpdate
195
+ ): void {
196
+ switch (update.type) {
197
+ case "text-delta": {
198
+ const acc = this.ensureNested(parentCallId);
199
+ acc.text += update.text;
200
+ this.emit({
201
+ type: "message.appended",
202
+ data: {
203
+ delta: update.text,
204
+ text: acc.text,
205
+ parentCallId,
206
+ },
207
+ });
208
+ return;
209
+ }
210
+ case "thinking-delta": {
211
+ const acc = this.ensureNested(parentCallId);
212
+ acc.reasoning += update.text;
213
+ this.emit({
214
+ type: "reasoning.appended",
215
+ data: {
216
+ delta: update.text,
217
+ text: acc.reasoning,
218
+ parentCallId,
219
+ },
220
+ });
221
+ return;
222
+ }
223
+ case "thinking-completed": {
224
+ const acc = this.nested.get(parentCallId);
225
+ if (acc !== undefined && acc.reasoning !== "") {
226
+ acc.reasoning = "";
227
+ }
228
+ this.emit({
229
+ type: "reasoning.completed",
230
+ data: {
231
+ durationMs: update.thinkingDurationMs,
232
+ parentCallId,
233
+ },
234
+ });
235
+ return;
236
+ }
237
+ case "tool-call-started": {
238
+ this.flushNestedAssistantText(parentCallId, "tool_call");
239
+ this.emitToolStarted(update.callId, update.toolCall, parentCallId);
240
+ return;
241
+ }
242
+ case "tool-call-completed": {
243
+ this.emitToolCompleted(update.callId, update.toolCall, parentCallId);
244
+ return;
245
+ }
246
+ case "partial-tool-call":
247
+ case "step-started":
248
+ case "step-completed":
249
+ return;
250
+ default: {
251
+ return;
252
+ }
253
+ }
254
+ }
255
+
256
+ private emitToolStarted(
257
+ callId: string,
258
+ toolCall: ToolCall,
259
+ parentCallId?: string
260
+ ): void {
261
+ const description = describeToolCall(toolCall);
262
+ this.emit({
263
+ type: "actions.requested",
264
+ data: {
265
+ calls: [
266
+ {
267
+ callId,
268
+ toolName: description.toolName,
269
+ args: description.args,
270
+ parentCallId,
271
+ },
272
+ ],
273
+ parentCallId,
274
+ },
275
+ });
276
+ // Subagent bookends only fire for the top-level task tool, not nested
277
+ // tools inside a subagent (nested subagents aren't supported).
278
+ if (description.subagent !== undefined && parentCallId === undefined) {
279
+ this.emit({
280
+ type: "subagent.called",
281
+ data: {
282
+ callId,
283
+ name: description.subagent.name,
284
+ description: description.subagent.description,
285
+ },
286
+ });
287
+ }
288
+ }
289
+
290
+ private emitToolCompleted(
291
+ callId: string,
292
+ toolCall: ToolCall,
293
+ parentCallId?: string
294
+ ): void {
295
+ const description = describeToolCall(toolCall);
296
+ const result = describeToolResult(toolCall);
297
+ this.emit({
298
+ type: "action.result",
299
+ data: {
300
+ callId,
301
+ toolName: description.toolName,
302
+ output: result.output,
303
+ isError: result.isError,
304
+ parentCallId,
305
+ },
306
+ });
307
+ if (description.subagent !== undefined && parentCallId === undefined) {
308
+ this.flushNestedAssistantText(callId, "stop");
309
+ this.nested.delete(callId);
310
+ this.emit({
311
+ type: "subagent.completed",
312
+ data: { callId, name: description.subagent.name },
313
+ });
314
+ }
315
+ }
316
+
317
+ private ensureNested(parentCallId: string): NestedAccumulators {
318
+ let acc = this.nested.get(parentCallId);
319
+ if (acc === undefined) {
320
+ acc = { text: "", reasoning: "" };
321
+ this.nested.set(parentCallId, acc);
322
+ }
323
+ return acc;
160
324
  }
161
325
 
162
326
  private flushAssistantText(finishReason: "stop" | "tool_call"): void {
@@ -171,6 +335,22 @@ export class TurnEventMapper {
171
335
  data: { text, finishReason },
172
336
  });
173
337
  }
338
+
339
+ private flushNestedAssistantText(
340
+ parentCallId: string,
341
+ finishReason: "stop" | "tool_call"
342
+ ): void {
343
+ const acc = this.nested.get(parentCallId);
344
+ if (acc === undefined || acc.text === "") {
345
+ return;
346
+ }
347
+ const text = acc.text;
348
+ acc.text = "";
349
+ this.emit({
350
+ type: "message.completed",
351
+ data: { text, finishReason, parentCallId },
352
+ });
353
+ }
174
354
  }
175
355
 
176
356
  /**
@@ -62,19 +62,17 @@ export function collectGitHubTriggerTargets(input: {
62
62
  }): AgentServeGitHubTriggerTarget[] {
63
63
  const targets: AgentServeGitHubTriggerTarget[] = [];
64
64
  for (const mount of input.mounts) {
65
- const github = mount.channels.find((channel) => channel.id === "github");
66
- if (github === undefined) {
67
- continue;
65
+ for (const channel of mount.channels) {
66
+ const options = getGitHubChannelOptions(channel.definition);
67
+ if (options === undefined) {
68
+ continue;
69
+ }
70
+ targets.push({
71
+ slug: mount.slug,
72
+ options,
73
+ args: mount.buildHandlerArgs(channel.id),
74
+ });
68
75
  }
69
- const options = getGitHubChannelOptions(github.definition);
70
- if (options === undefined) {
71
- continue;
72
- }
73
- targets.push({
74
- slug: mount.slug,
75
- options,
76
- args: mount.buildHandlerArgs("github"),
77
- });
78
76
  }
79
77
  return targets;
80
78
  }
@@ -12,6 +12,7 @@ import {
12
12
  resolveGitHubInstallationId,
13
13
  tryResolveGhAuthToken,
14
14
  } from "../channels/github/auth.js";
15
+ import type { GitHubChannelCredentials } from "../channels/github/types.js";
15
16
  import { tryResolveBotToken } from "../channels/slack/credentials.js";
16
17
  import type { HostGitHubClient, HostSlackClient } from "../types.js";
17
18
 
@@ -25,21 +26,34 @@ export interface HostPlatforms {
25
26
  * `app` = GitHub App installation token (preferred in production).
26
27
  * `env` / `gh` = local PAT / CLI fallbacks when App creds are unset.
27
28
  */
28
- export type HostGitHubAuthSource = "app" | "env" | "gh" | "unavailable";
29
+ export type HostGitHubAuthSource =
30
+ | "app"
31
+ | "cursor-account"
32
+ | "env"
33
+ | "gh"
34
+ | "unavailable";
35
+
36
+ export interface HostPlatformsOptions {
37
+ githubCredentials?: GitHubChannelCredentials;
38
+ }
29
39
 
30
40
  /**
31
41
  * Build host platforms from ambient credentials. Prefer App installation
32
42
  * auth when configured; otherwise fall back to PAT / `gh auth` for local
33
43
  * testing. Webhook-scoped calls should still prefer `ctx.github`.
34
44
  */
35
- export function createHostPlatforms(): HostPlatforms {
45
+ export function createHostPlatforms(
46
+ options: HostPlatformsOptions = {}
47
+ ): HostPlatforms {
36
48
  let octokitPromise: ReturnType<HostGitHubClient["getOctokit"]> | undefined;
37
49
  let slackPromise: ReturnType<HostSlackClient["getClient"]> | undefined;
38
50
 
39
51
  return {
40
52
  github: {
41
53
  getOctokit: () => {
42
- octokitPromise ??= createGitHubOctokit({});
54
+ octokitPromise ??= createGitHubOctokit({
55
+ credentials: options.githubCredentials,
56
+ });
43
57
  return octokitPromise;
44
58
  },
45
59
  },
@@ -95,8 +109,9 @@ export async function resolveHostGitHubAuthSource(): Promise<HostGitHubAuthSourc
95
109
  export async function warmupHostGitHubAuth(options: {
96
110
  logger: (line: string) => void;
97
111
  github?: HostGitHubClient;
112
+ authSource?: HostGitHubAuthSource;
98
113
  }): Promise<HostGitHubAuthSource> {
99
- const source = await resolveHostGitHubAuthSource();
114
+ const source = options.authSource ?? (await resolveHostGitHubAuthSource());
100
115
  if (source === "unavailable") {
101
116
  options.logger(
102
117
  "[agent-serve] GitHub auth: unavailable (set GITHUB_APP_ID + GITHUB_APP_PRIVATE_KEY + GITHUB_APP_INSTALLATION_ID, or GITHUB_TOKEN / GH_TOKEN, or run `gh auth login`)"
@@ -118,13 +133,15 @@ export async function warmupHostGitHubAuth(options: {
118
133
  }
119
134
 
120
135
  const label =
121
- source === "app"
122
- ? exportedGhToken
123
- ? "GitHub App installation token (also exported as GH_TOKEN for gh CLI)"
124
- : "GitHub App installation token"
125
- : source === "env"
126
- ? "GITHUB_TOKEN/GH_TOKEN"
127
- : "gh auth token";
136
+ source === "cursor-account"
137
+ ? "Cursor account repo-scoped credential (also exported as GH_TOKEN for gh CLI)"
138
+ : source === "app"
139
+ ? exportedGhToken
140
+ ? "GitHub App installation token (also exported as GH_TOKEN for gh CLI)"
141
+ : "GitHub App installation token"
142
+ : source === "env"
143
+ ? "GITHUB_TOKEN/GH_TOKEN"
144
+ : "gh auth token";
128
145
  if (options.github === undefined) {
129
146
  options.logger(`[agent-serve] GitHub auth: ${label}`);
130
147
  return source;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Client-side mirrors of the Agent Serve hosting validation rules
3
+ * (backend/server/src/agentServe/agentServeShared.ts). Shared by discovery
4
+ * (`hosting` block diagnostics on `agentkit validate`) and the deploy /
5
+ * secrets CLI verbs (actionable errors before any network call). The
6
+ * backend stays authoritative — these exist so mistakes fail fast and
7
+ * locally with the same grammar the server enforces.
8
+ */
9
+
10
+ /** `hosting.egressDomains` cap (backend caps the deploy body at 20). */
11
+ export const MAX_EGRESS_DOMAINS = 20;
12
+ /** Max secrets per deployment. */
13
+ export const MAX_SECRETS = 32;
14
+ /** Max secret value size in bytes. */
15
+ export const MAX_SECRET_VALUE_BYTES = 4096;
16
+ /** Max secret name length. */
17
+ export const MAX_SECRET_NAME_LENGTH = 64;
18
+ /** Secret names the platform injects; user writes are rejected. */
19
+ export const RESERVED_SECRET_NAME_PREFIX = "CURSOR_";
20
+
21
+ const SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
22
+
23
+ // Lowercase hostname with >=2 labels, an alphabetic TLD, and at most one
24
+ // leading `*.` wildcard. Labels: alphanumeric with interior hyphens.
25
+ const EGRESS_DOMAIN_PATTERN =
26
+ /^(\*\.)?([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]+$/;
27
+
28
+ /** Returns a human error message, or undefined when the domain is valid. */
29
+ export function validateEgressDomain(domain: string): string | undefined {
30
+ if (EGRESS_DOMAIN_PATTERN.test(domain)) {
31
+ return undefined;
32
+ }
33
+ return `Invalid egress domain ${JSON.stringify(domain)}: use a lowercase hostname with at least two labels and an alphabetic TLD (e.g. "api.example.com"), optionally with a single leading "*." wildcard.`;
34
+ }
35
+
36
+ /**
37
+ * Returns a human error message, or undefined when the name is a valid
38
+ * secret name. Grammar only — reserved names are checked separately so the
39
+ * manifest's declarative `secretNames` can mention them with a softer
40
+ * diagnostic than the hard write-time rejection.
41
+ */
42
+ export function validateSecretName(name: string): string | undefined {
43
+ if (name.length > MAX_SECRET_NAME_LENGTH) {
44
+ return `Secret name ${JSON.stringify(name)} is too long (max ${MAX_SECRET_NAME_LENGTH} characters).`;
45
+ }
46
+ if (!SECRET_NAME_PATTERN.test(name)) {
47
+ return `Invalid secret name ${JSON.stringify(name)}: use UPPER_SNAKE_CASE starting with a letter (${SECRET_NAME_PATTERN}).`;
48
+ }
49
+ return undefined;
50
+ }
51
+
52
+ /** True when the platform reserves this name (`CURSOR_*`); writes are rejected. */
53
+ export function isReservedSecretName(name: string): boolean {
54
+ return name.startsWith(RESERVED_SECRET_NAME_PREFIX);
55
+ }
56
+
57
+ /**
58
+ * Human error for a secret name a user is trying to write or delete:
59
+ * grammar plus the reserved `CURSOR_*` prefix.
60
+ */
61
+ export function validateSettableSecretName(name: string): string | undefined {
62
+ const nameError = validateSecretName(name);
63
+ if (nameError !== undefined) {
64
+ return nameError;
65
+ }
66
+ if (isReservedSecretName(name)) {
67
+ return `Secret name ${JSON.stringify(name)} is platform-reserved (CURSOR_*); the platform injects those values automatically.`;
68
+ }
69
+ return undefined;
70
+ }
71
+
72
+ const CURSOR_EVENT_REPO_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
73
+
74
+ /** `owner/name` — mirrors the backend's cursor-event repo grammar. */
75
+ export function isValidCursorEventRepo(repo: string): boolean {
76
+ return CURSOR_EVENT_REPO_PATTERN.test(repo) && !repo.includes("..");
77
+ }