@cursor/july 0.1.105 → 0.1.108

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 (395) hide show
  1. package/README.md +10 -5
  2. package/dist/bin/agent-serve.js +31 -16
  3. package/dist/channels/bitbucket/types.d.ts +2 -4
  4. package/dist/channels/bitbucket/types.d.ts.map +1 -1
  5. package/dist/channels/deployments/types.d.ts +5 -8
  6. package/dist/channels/deployments/types.d.ts.map +1 -1
  7. package/dist/channels/github/github-channel.js +8 -5
  8. package/dist/channels/github/types.d.ts +7 -5
  9. package/dist/channels/github/types.d.ts.map +1 -1
  10. package/dist/channels/gitlab/types.d.ts +2 -5
  11. package/dist/channels/gitlab/types.d.ts.map +1 -1
  12. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  13. package/dist/channels/origin/origin-channel.js +27 -13
  14. package/dist/channels/origin/types.d.ts +7 -4
  15. package/dist/channels/origin/types.d.ts.map +1 -1
  16. package/dist/channels/slack/defaults.d.ts.map +1 -1
  17. package/dist/channels/slack/defaults.js +3 -0
  18. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  19. package/dist/channels/slack/dispatch.js +1 -1
  20. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  21. package/dist/channels/slack/live-delivery.js +48 -11
  22. package/dist/channels/slack/types.d.ts +4 -3
  23. package/dist/channels/slack/types.d.ts.map +1 -1
  24. package/dist/channels.d.ts +45 -0
  25. package/dist/channels.d.ts.map +1 -1
  26. package/dist/channels.js +106 -7
  27. package/dist/connections.d.ts +2 -1
  28. package/dist/connections.d.ts.map +1 -1
  29. package/dist/connections.js +2 -1
  30. package/dist/docs/404.html +3 -3
  31. package/dist/docs/ab.html +6 -6
  32. package/dist/docs/assets/{app.BVwaffdK.js → app.BASKM3M4.js} +1 -1
  33. package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +1 -0
  34. package/dist/docs/assets/chunks/{VPLocalSearchBox.WuWTZ1x8.js → VPLocalSearchBox.BOKxlYGP.js} +2 -2
  35. package/dist/docs/assets/chunks/{theme.BYdI_6sF.js → theme.DbDZW-zb.js} +2 -2
  36. package/dist/docs/assets/{deployment.md.MFPKqsqI.js → deployment.md.JenwuCCB.js} +4 -4
  37. package/dist/docs/assets/{deployment.md.MFPKqsqI.lean.js → deployment.md.JenwuCCB.lean.js} +1 -1
  38. package/dist/docs/assets/{evals.md.CbMoebP1.js → evals.md.C1ekS3k2.js} +1 -1
  39. package/dist/docs/assets/guides_cloud-agents.md.BsloyHdY.js +9 -0
  40. package/dist/docs/assets/{guides_cloud-agents.md.DS8RIjwx.lean.js → guides_cloud-agents.md.BsloyHdY.lean.js} +1 -1
  41. package/dist/docs/assets/{guides_github.md.c0gdGJ-D.js → guides_github.md.BH33UEBJ.js} +1 -1
  42. package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.js → guides_grokbot-agents.md.DyV-WArv.js} +1 -1
  43. package/dist/docs/assets/guides_improve.md.BGVk32bK.js +14 -0
  44. package/dist/docs/assets/guides_improve.md.BGVk32bK.lean.js +1 -0
  45. package/dist/docs/assets/{guides_opentelemetry.md.COh9jFVg.js → guides_opentelemetry.md.SCRMskno.js} +3 -3
  46. package/dist/docs/assets/{guides_opentelemetry.md.COh9jFVg.lean.js → guides_opentelemetry.md.SCRMskno.lean.js} +1 -1
  47. package/dist/docs/assets/{guides_slack.md.9oHPye9o.js → guides_slack.md.D4RVMM4G.js} +3 -3
  48. package/dist/docs/assets/{guides_slack.md.9oHPye9o.lean.js → guides_slack.md.D4RVMM4G.lean.js} +1 -1
  49. package/dist/docs/assets/index.md.BjH1w2ZW.js +5 -0
  50. package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.js → reference_agent-config.md.CvoL6pof.js} +1 -1
  51. package/dist/docs/assets/{reference_channels.md.DBGcaB7m.js → reference_channels.md.D-qTqwcq.js} +2 -2
  52. package/dist/docs/assets/{reference_channels.md.DBGcaB7m.lean.js → reference_channels.md.D-qTqwcq.lean.js} +1 -1
  53. package/dist/docs/assets/{reference_cli.md.C6Lo8SEd.js → reference_cli.md.Ca26u0Es.js} +6 -6
  54. package/dist/docs/assets/{reference_cli.md.C6Lo8SEd.lean.js → reference_cli.md.Ca26u0Es.lean.js} +1 -1
  55. package/dist/docs/assets/{reference_connections.md.Di6jJAXF.js → reference_connections.md.BojkC6c5.js} +1 -1
  56. package/dist/docs/assets/{reference_extensions.md.CGmMLblt.js → reference_extensions.md.CPWt00ds.js} +1 -1
  57. package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.js → scaffolding-agents.md.Kctn3OVb.js} +1 -1
  58. package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.js → skills_create-agent.md.Q3h6Je-e.js} +1 -1
  59. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.js → skills_debug.md.CVjCXMFF.js} +1 -1
  60. package/dist/docs/assets/{skills_debug.md.CDbPhHfg.lean.js → skills_debug.md.CVjCXMFF.lean.js} +1 -1
  61. package/dist/docs/assets/{skills_evals.md.723kpUmA.js → skills_evals.md.BhovOvrl.js} +1 -1
  62. package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.js +1 -0
  63. package/dist/docs/assets/{skills_framework-map.md.haibFyoB.lean.js → skills_framework-map.md.D-tFZhFS.lean.js} +1 -1
  64. package/dist/docs/assets/{skills_github.md.D0JahM8c.js → skills_github.md.hgFX_oKY.js} +1 -1
  65. package/dist/docs/assets/{skills_otel.md.CqhobH3B.js → skills_otel.md.B5Ddv1xH.js} +1 -1
  66. package/dist/docs/assets/{style.BRuM8477.css → style.DCD_zyg3.css} +1 -1
  67. package/dist/docs/assets/troubleshooting.md.CYEAO9bM.js +1 -0
  68. package/dist/docs/building-with-agents.html +6 -6
  69. package/dist/docs/concepts.html +5 -5
  70. package/dist/docs/deployment.html +9 -9
  71. package/dist/docs/deployment.md +7 -2
  72. package/dist/docs/evals.html +8 -8
  73. package/dist/docs/evals.md +3 -2
  74. package/dist/docs/guides/agent-to-agent.html +6 -6
  75. package/dist/docs/guides/cloud-agents.html +7 -7
  76. package/dist/docs/guides/cloud-agents.md +4 -3
  77. package/dist/docs/guides/convert-automation.html +6 -6
  78. package/dist/docs/guides/github.html +7 -7
  79. package/dist/docs/guides/github.md +2 -1
  80. package/dist/docs/guides/grokbot-agents.html +7 -7
  81. package/dist/docs/guides/grokbot-agents.md +2 -2
  82. package/dist/docs/guides/human-in-the-loop.html +6 -6
  83. package/dist/docs/guides/improve.html +40 -0
  84. package/dist/docs/guides/improve.md +91 -0
  85. package/dist/docs/guides/mcp-oauth.html +6 -6
  86. package/dist/docs/guides/opentelemetry.html +8 -8
  87. package/dist/docs/guides/opentelemetry.md +3 -4
  88. package/dist/docs/guides/slack.html +8 -8
  89. package/dist/docs/guides/slack.md +2 -1
  90. package/dist/docs/guides/webhooks.html +6 -6
  91. package/dist/docs/hashmap.json +1 -1
  92. package/dist/docs/hillclimbing.html +6 -6
  93. package/dist/docs/index.html +8 -8
  94. package/dist/docs/index.md +4 -0
  95. package/dist/docs/llms-full.txt +180 -61
  96. package/dist/docs/llms.txt +1 -0
  97. package/dist/docs/quickstart.html +6 -6
  98. package/dist/docs/reference/agent-config.html +7 -7
  99. package/dist/docs/reference/agent-config.md +5 -2
  100. package/dist/docs/reference/artifacts.html +6 -6
  101. package/dist/docs/reference/channels.html +7 -7
  102. package/dist/docs/reference/channels.md +11 -19
  103. package/dist/docs/reference/cli.html +11 -11
  104. package/dist/docs/reference/cli.md +23 -13
  105. package/dist/docs/reference/connections.html +8 -8
  106. package/dist/docs/reference/connections.md +2 -1
  107. package/dist/docs/reference/extensions.html +7 -7
  108. package/dist/docs/reference/extensions.md +2 -0
  109. package/dist/docs/reference/hooks.html +6 -6
  110. package/dist/docs/reference/http-api.html +6 -6
  111. package/dist/docs/reference/instructions.html +6 -6
  112. package/dist/docs/reference/playground.html +5 -5
  113. package/dist/docs/reference/project-layout.html +6 -6
  114. package/dist/docs/reference/prompt.html +6 -6
  115. package/dist/docs/reference/result.html +6 -6
  116. package/dist/docs/reference/schedules.html +6 -6
  117. package/dist/docs/reference/sessions.html +5 -5
  118. package/dist/docs/reference/skills.html +6 -6
  119. package/dist/docs/reference/subagents.html +6 -6
  120. package/dist/docs/reference/tools.html +6 -6
  121. package/dist/docs/scaffolding-agents.html +6 -6
  122. package/dist/docs/scaffolding-agents.md +2 -1
  123. package/dist/docs/skills/ab.html +6 -6
  124. package/dist/docs/skills/create-agent.html +8 -8
  125. package/dist/docs/skills/create-agent.md +1 -1
  126. package/dist/docs/skills/debug.html +6 -6
  127. package/dist/docs/skills/debug.md +1 -1
  128. package/dist/docs/skills/evals.html +8 -8
  129. package/dist/docs/skills/evals.md +1 -1
  130. package/dist/docs/skills/framework-map.html +6 -6
  131. package/dist/docs/skills/framework-map.md +4 -2
  132. package/dist/docs/skills/github.html +8 -8
  133. package/dist/docs/skills/github.md +1 -1
  134. package/dist/docs/skills/hillclimb.html +6 -6
  135. package/dist/docs/skills/index.html +5 -5
  136. package/dist/docs/skills/mcp-auth.html +6 -6
  137. package/dist/docs/skills/otel.html +8 -8
  138. package/dist/docs/skills/otel.md +3 -3
  139. package/dist/docs/skills/setup-slack.html +6 -6
  140. package/dist/docs/storage.html +6 -6
  141. package/dist/docs/templates/agentic-owners.html +6 -6
  142. package/dist/docs/templates/agents-md.html +6 -6
  143. package/dist/docs/templates/code-wiki.html +6 -6
  144. package/dist/docs/templates/demo.html +6 -6
  145. package/dist/docs/templates/grokbot-agents.html +6 -6
  146. package/dist/docs/templates/pr-autofixer.html +6 -6
  147. package/dist/docs/templates/security-help.html +6 -6
  148. package/dist/docs/templates/security-reviewer.html +6 -6
  149. package/dist/docs/templates/triage.html +6 -6
  150. package/dist/docs/troubleshooting.html +6 -6
  151. package/dist/docs/troubleshooting.md +1 -1
  152. package/dist/extensions/improve/extension.d.ts +46 -0
  153. package/dist/extensions/improve/extension.d.ts.map +1 -0
  154. package/dist/extensions/improve/extension.js +41 -0
  155. package/dist/extensions/improve/skills/yourself.d.ts +4 -0
  156. package/dist/extensions/improve/skills/yourself.d.ts.map +1 -0
  157. package/dist/extensions/improve/skills/yourself.js +43 -0
  158. package/dist/index.d.ts +4 -5
  159. package/dist/index.d.ts.map +1 -1
  160. package/dist/index.js +3 -4
  161. package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
  162. package/dist/internal/builtin-tools/artifacts.js +2 -3
  163. package/dist/internal/channel-route-dispatch.d.ts +13 -0
  164. package/dist/internal/channel-route-dispatch.d.ts.map +1 -0
  165. package/dist/internal/channel-route-dispatch.js +62 -0
  166. package/dist/internal/channel-state.d.ts +17 -0
  167. package/dist/internal/channel-state.d.ts.map +1 -0
  168. package/dist/internal/channel-state.js +78 -0
  169. package/dist/internal/cli-ax.d.ts +7 -0
  170. package/dist/internal/cli-ax.d.ts.map +1 -1
  171. package/dist/internal/cli-ax.js +99 -1
  172. package/dist/internal/cli-cursor.d.ts.map +1 -1
  173. package/dist/internal/cli-cursor.js +2 -0
  174. package/dist/internal/cli-deploy.d.ts.map +1 -1
  175. package/dist/internal/cli-deploy.js +61 -25
  176. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  177. package/dist/internal/cli-mcp-oauth.js +15 -0
  178. package/dist/internal/cli-mcp.d.ts.map +1 -1
  179. package/dist/internal/cli-mcp.js +12 -0
  180. package/dist/internal/cli-slack.d.ts.map +1 -1
  181. package/dist/internal/cli-slack.js +8 -2
  182. package/dist/internal/cursor/backend-client.d.ts +25 -0
  183. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  184. package/dist/internal/cursor/backend-client.js +57 -2
  185. package/dist/internal/cursor/credentials.d.ts +8 -2
  186. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  187. package/dist/internal/cursor/credentials.js +27 -5
  188. package/dist/internal/deploy-client.d.ts +35 -0
  189. package/dist/internal/deploy-client.d.ts.map +1 -1
  190. package/dist/internal/deploy-client.js +46 -0
  191. package/dist/internal/deploy-manifest.d.ts +26 -0
  192. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  193. package/dist/internal/deploy-manifest.js +99 -13
  194. package/dist/internal/describe-error.d.ts +1 -0
  195. package/dist/internal/describe-error.d.ts.map +1 -1
  196. package/dist/internal/describe-error.js +25 -0
  197. package/dist/internal/discovery/agent.d.ts.map +1 -1
  198. package/dist/internal/discovery/agent.js +1 -0
  199. package/dist/internal/discovery/info.d.ts.map +1 -1
  200. package/dist/internal/discovery/info.js +7 -3
  201. package/dist/internal/discovery/modules.d.ts +1 -1
  202. package/dist/internal/discovery/modules.d.ts.map +1 -1
  203. package/dist/internal/discovery/modules.js +1 -0
  204. package/dist/internal/discovery/project.d.ts.map +1 -1
  205. package/dist/internal/discovery/project.js +3 -0
  206. package/dist/internal/discovery/reminders.d.ts +7 -0
  207. package/dist/internal/discovery/reminders.d.ts.map +1 -0
  208. package/dist/internal/discovery/reminders.js +65 -0
  209. package/dist/internal/discovery/subagent.js +1 -0
  210. package/dist/internal/distribution.d.ts +5 -0
  211. package/dist/internal/distribution.d.ts.map +1 -1
  212. package/dist/internal/distribution.js +17 -0
  213. package/dist/internal/framework-storage-selection.d.ts +14 -3
  214. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  215. package/dist/internal/framework-storage-selection.js +36 -6
  216. package/dist/internal/guest-network.d.ts +4 -10
  217. package/dist/internal/guest-network.d.ts.map +1 -1
  218. package/dist/internal/guest-network.js +44 -26
  219. package/dist/internal/hosted-admission-adapter.d.ts +2 -0
  220. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
  221. package/dist/internal/hosted-catch-protocol.d.ts +51 -0
  222. package/dist/internal/hosted-catch-protocol.d.ts.map +1 -0
  223. package/dist/internal/hosted-catch-protocol.js +103 -0
  224. package/dist/internal/hosted-catch.d.ts +40 -0
  225. package/dist/internal/hosted-catch.d.ts.map +1 -0
  226. package/dist/internal/hosted-catch.js +149 -0
  227. package/dist/internal/hosted-delivery-protocol.d.ts +89 -0
  228. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  229. package/dist/internal/hosted-delivery-protocol.js +309 -0
  230. package/dist/internal/hosted-delivery.d.ts +20 -1
  231. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  232. package/dist/internal/hosted-delivery.js +179 -36
  233. package/dist/internal/hosted-execution-diag.d.ts +4 -1
  234. package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
  235. package/dist/internal/hosted-execution-diag.js +13 -4
  236. package/dist/internal/hosted-execution-flush.d.ts +3 -0
  237. package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
  238. package/dist/internal/hosted-execution-flush.js +2 -4
  239. package/dist/internal/http-control-plane-session.d.ts +30 -0
  240. package/dist/internal/http-control-plane-session.d.ts.map +1 -0
  241. package/dist/internal/http-control-plane-session.js +83 -0
  242. package/dist/internal/legacy-command-guard.d.ts +22 -0
  243. package/dist/internal/legacy-command-guard.d.ts.map +1 -0
  244. package/dist/internal/legacy-command-guard.js +51 -0
  245. package/dist/internal/local-control-plane.d.ts +18 -2
  246. package/dist/internal/local-control-plane.d.ts.map +1 -1
  247. package/dist/internal/local-control-plane.js +199 -17
  248. package/dist/internal/platform-timers.d.ts +7 -0
  249. package/dist/internal/platform-timers.d.ts.map +1 -1
  250. package/dist/internal/platform-timers.js +139 -0
  251. package/dist/internal/reminder-control-plane-protocol.d.ts +189 -0
  252. package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -0
  253. package/dist/internal/reminder-control-plane-protocol.js +251 -0
  254. package/dist/internal/reminder-runner.d.ts +56 -6
  255. package/dist/internal/reminder-runner.d.ts.map +1 -1
  256. package/dist/internal/reminder-runner.js +372 -57
  257. package/dist/internal/reminder-schedule.d.ts +5 -2
  258. package/dist/internal/reminder-schedule.d.ts.map +1 -1
  259. package/dist/internal/reminder-schedule.js +8 -6
  260. package/dist/internal/reminder-store.d.ts +24 -7
  261. package/dist/internal/reminder-store.d.ts.map +1 -1
  262. package/dist/internal/reminder-store.js +6 -5
  263. package/dist/internal/request-error-status.d.ts +2 -0
  264. package/dist/internal/request-error-status.d.ts.map +1 -1
  265. package/dist/internal/request-error-status.js +22 -3
  266. package/dist/internal/resolve-prod-target.d.ts +2 -0
  267. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  268. package/dist/internal/resolve-prod-target.js +13 -0
  269. package/dist/internal/scm/pr-url.d.ts +40 -0
  270. package/dist/internal/scm/pr-url.d.ts.map +1 -1
  271. package/dist/internal/scm/pr-url.js +93 -14
  272. package/dist/internal/sdk-runner.d.ts.map +1 -1
  273. package/dist/internal/sdk-runner.js +4 -3
  274. package/dist/internal/server.d.ts.map +1 -1
  275. package/dist/internal/server.js +118 -77
  276. package/dist/internal/session-engine.d.ts +6 -6
  277. package/dist/internal/session-engine.d.ts.map +1 -1
  278. package/dist/internal/session-engine.js +100 -67
  279. package/dist/playground/assets/{index-BaQzjaNK.js → index-BMDqAeXu.js} +34 -34
  280. package/dist/playground/assets/index-LUgJoWdL.css +1 -0
  281. package/dist/playground/index.html +2 -2
  282. package/dist/reminders.d.ts +24 -5
  283. package/dist/reminders.d.ts.map +1 -1
  284. package/dist/reminders.js +28 -5
  285. package/dist/storage-backends/cursor-hosted.d.ts +6 -0
  286. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  287. package/dist/storage-backends/cursor-hosted.js +29 -1
  288. package/dist/types.d.ts +122 -25
  289. package/dist/types.d.ts.map +1 -1
  290. package/docs/README.md +4 -0
  291. package/docs/deployment.md +7 -2
  292. package/docs/evals.md +3 -2
  293. package/docs/guides/cloud-agents.md +4 -3
  294. package/docs/guides/github.md +2 -1
  295. package/docs/guides/grokbot-agents.md +2 -2
  296. package/docs/guides/improve.md +96 -0
  297. package/docs/guides/opentelemetry.md +3 -4
  298. package/docs/guides/slack.md +2 -1
  299. package/docs/reference/agent-config.md +5 -2
  300. package/docs/reference/channels.md +11 -19
  301. package/docs/reference/cli.md +23 -13
  302. package/docs/reference/connections.md +2 -1
  303. package/docs/reference/extensions.md +2 -0
  304. package/docs/scaffolding-agents.md +2 -1
  305. package/docs/troubleshooting.md +1 -1
  306. package/package.json +10 -3
  307. package/skills/create-agent/SKILL.md +1 -1
  308. package/skills/debug/SKILL.md +1 -1
  309. package/skills/evals/SKILL.md +1 -1
  310. package/skills/framework-map/SKILL.md +4 -2
  311. package/skills/github/SKILL.md +1 -1
  312. package/skills/otel/SKILL.md +3 -3
  313. package/src/bin/agent-serve.ts +28 -11
  314. package/src/channels/bitbucket/types.ts +2 -4
  315. package/src/channels/deployments/types.ts +5 -8
  316. package/src/channels/github/github-channel.ts +8 -8
  317. package/src/channels/github/types.ts +7 -4
  318. package/src/channels/gitlab/types.ts +2 -5
  319. package/src/channels/origin/origin-channel.ts +29 -13
  320. package/src/channels/origin/types.ts +7 -3
  321. package/src/channels/slack/defaults.ts +3 -0
  322. package/src/channels/slack/dispatch.ts +1 -0
  323. package/src/channels/slack/live-delivery.ts +53 -12
  324. package/src/channels/slack/types.ts +4 -3
  325. package/src/channels.ts +157 -10
  326. package/src/connections.ts +2 -1
  327. package/src/extensions/improve/extension.ts +70 -0
  328. package/src/extensions/improve/skills/yourself.ts +50 -0
  329. package/src/index.ts +6 -3
  330. package/src/internal/builtin-tools/artifacts.ts +2 -3
  331. package/src/internal/channel-route-dispatch.ts +66 -0
  332. package/src/internal/channel-state.ts +96 -0
  333. package/src/internal/cli-ax.ts +110 -1
  334. package/src/internal/cli-cursor.ts +4 -1
  335. package/src/internal/cli-deploy.ts +80 -22
  336. package/src/internal/cli-mcp-oauth.ts +18 -0
  337. package/src/internal/cli-mcp.ts +11 -0
  338. package/src/internal/cli-slack.ts +15 -2
  339. package/src/internal/cursor/backend-client.ts +90 -2
  340. package/src/internal/cursor/credentials.ts +35 -7
  341. package/src/internal/deploy-client.ts +70 -0
  342. package/src/internal/deploy-manifest.ts +131 -12
  343. package/src/internal/describe-error.ts +28 -0
  344. package/src/internal/discovery/agent.ts +1 -0
  345. package/src/internal/discovery/info.ts +6 -0
  346. package/src/internal/discovery/modules.ts +2 -4
  347. package/src/internal/discovery/project.ts +3 -0
  348. package/src/internal/discovery/reminders.ts +65 -0
  349. package/src/internal/discovery/subagent.ts +1 -0
  350. package/src/internal/distribution.ts +20 -0
  351. package/src/internal/framework-storage-selection.ts +43 -6
  352. package/src/internal/guest-network.ts +46 -29
  353. package/src/internal/hosted-admission-adapter.ts +2 -0
  354. package/src/internal/hosted-catch-protocol.ts +130 -0
  355. package/src/internal/hosted-catch.ts +192 -0
  356. package/src/internal/hosted-delivery-protocol.ts +483 -0
  357. package/src/internal/hosted-delivery.ts +303 -43
  358. package/src/internal/hosted-execution-diag.ts +21 -3
  359. package/src/internal/hosted-execution-flush.ts +6 -3
  360. package/src/internal/http-control-plane-session.ts +104 -0
  361. package/src/internal/legacy-command-guard.ts +59 -0
  362. package/src/internal/local-control-plane.ts +281 -22
  363. package/src/internal/platform-timers.ts +191 -0
  364. package/src/internal/reminder-control-plane-protocol.ts +512 -0
  365. package/src/internal/reminder-runner.ts +481 -57
  366. package/src/internal/reminder-schedule.ts +11 -6
  367. package/src/internal/reminder-store.ts +27 -7
  368. package/src/internal/request-error-status.ts +27 -3
  369. package/src/internal/resolve-prod-target.ts +15 -0
  370. package/src/internal/scm/pr-url.ts +167 -20
  371. package/src/internal/sdk-runner.ts +2 -1
  372. package/src/internal/server.ts +151 -88
  373. package/src/internal/session-engine.ts +146 -83
  374. package/src/reminders.ts +35 -4
  375. package/src/storage-backends/cursor-hosted.ts +40 -1
  376. package/src/types.ts +134 -26
  377. package/dist/docs/assets/chunks/@localSearchIndexroot.CJxMklAy.js +0 -1
  378. package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +0 -9
  379. package/dist/docs/assets/index.md.BW_6tOgR.js +0 -5
  380. package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +0 -1
  381. package/dist/docs/assets/troubleshooting.md.Cus_YZga.js +0 -1
  382. package/dist/playground/assets/index-CceqnLTX.css +0 -1
  383. /package/dist/docs/assets/{evals.md.CbMoebP1.lean.js → evals.md.C1ekS3k2.lean.js} +0 -0
  384. /package/dist/docs/assets/{guides_github.md.c0gdGJ-D.lean.js → guides_github.md.BH33UEBJ.lean.js} +0 -0
  385. /package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.lean.js → guides_grokbot-agents.md.DyV-WArv.lean.js} +0 -0
  386. /package/dist/docs/assets/{index.md.BW_6tOgR.lean.js → index.md.BjH1w2ZW.lean.js} +0 -0
  387. /package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.lean.js → reference_agent-config.md.CvoL6pof.lean.js} +0 -0
  388. /package/dist/docs/assets/{reference_connections.md.Di6jJAXF.lean.js → reference_connections.md.BojkC6c5.lean.js} +0 -0
  389. /package/dist/docs/assets/{reference_extensions.md.CGmMLblt.lean.js → reference_extensions.md.CPWt00ds.lean.js} +0 -0
  390. /package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.lean.js → scaffolding-agents.md.Kctn3OVb.lean.js} +0 -0
  391. /package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.lean.js → skills_create-agent.md.Q3h6Je-e.lean.js} +0 -0
  392. /package/dist/docs/assets/{skills_evals.md.723kpUmA.lean.js → skills_evals.md.BhovOvrl.lean.js} +0 -0
  393. /package/dist/docs/assets/{skills_github.md.D0JahM8c.lean.js → skills_github.md.hgFX_oKY.lean.js} +0 -0
  394. /package/dist/docs/assets/{skills_otel.md.CqhobH3B.lean.js → skills_otel.md.B5Ddv1xH.lean.js} +0 -0
  395. /package/dist/docs/assets/{troubleshooting.md.Cus_YZga.lean.js → troubleshooting.md.CYEAO9bM.lean.js} +0 -0
@@ -3,6 +3,7 @@ import type {
3
3
  AuthPolicy,
4
4
  ChannelHandlerArgs,
5
5
  SendMessageOptions,
6
+ TurnOutcome,
6
7
  } from "../types.js";
7
8
  import { dispatchOutcome } from "./channel-dispatch.js";
8
9
  import {
@@ -20,7 +21,6 @@ import {
20
21
  GuestNetworkUnavailableError,
21
22
  type GuestNetworkWaitResult,
22
23
  type GuestNetworkWaitStats,
23
- isQuietGuestConnectStallMessage,
24
24
  waitForGuestNetworkReady,
25
25
  } from "./guest-network.js";
26
26
  import {
@@ -36,9 +36,18 @@ import {
36
36
  HOSTED_DELIVERY_HEADER,
37
37
  HOSTED_DELIVERY_PROTOCOL_VERSION,
38
38
  HOSTED_EXECUTION_PATH,
39
+ HOSTED_GUEST_RETRY_TERMINAL,
40
+ HOSTED_GUEST_RETRY_TRANSIENT,
39
41
  type HostedAdmission,
42
+ type HostedGuestRetryDisposition,
43
+ type HostedReminderFireDescriptorPayload,
44
+ hostedFailureClassification,
45
+ hostedGuestErrorResponse,
46
+ isHostedReminderAdmission,
40
47
  parseHostedAdmission,
41
48
  parseHostedExecution,
49
+ parseHostedReminderFireDescriptorPayload,
50
+ parseHostedReminderFirePayload,
42
51
  } from "./hosted-delivery-protocol.js";
43
52
  import {
44
53
  abortReasonFromTurnStatus,
@@ -50,10 +59,17 @@ import {
50
59
  type HostedExecutionFlushSinks,
51
60
  } from "./hosted-execution-flush.js";
52
61
  import { recordHostedManagedAutomation } from "./hosted-managed-automation.js";
53
- import { errorResponse, readJsonObject } from "./http-channel.js";
62
+ import { readJsonObject } from "./http-channel.js";
54
63
  import type { LogRingEntry } from "./log-ring.js";
55
64
  import { endActiveHttpSpan } from "./otel/http.js";
56
- import { statusForThrownRequestError } from "./request-error-status.js";
65
+ import {
66
+ ReminderValidationError,
67
+ UnknownReminderError,
68
+ } from "./reminder-runner.js";
69
+ import {
70
+ mapThrownRequestError,
71
+ statusForThrownRequestError,
72
+ } from "./request-error-status.js";
57
73
  import type { Router } from "./router.js";
58
74
  import type { SessionRunExecutionWrite } from "./session-run-log.js";
59
75
 
@@ -108,6 +124,32 @@ function boundedMessage(text: string): string {
108
124
  : text;
109
125
  }
110
126
 
127
+ function terminalHostedError(
128
+ status: number,
129
+ error: string,
130
+ message?: string
131
+ ): Response {
132
+ return hostedGuestErrorResponse({
133
+ status,
134
+ error,
135
+ retry: HOSTED_GUEST_RETRY_TERMINAL,
136
+ message,
137
+ });
138
+ }
139
+
140
+ function transientHostedError(
141
+ status: number,
142
+ error: string,
143
+ message?: string
144
+ ): Response {
145
+ return hostedGuestErrorResponse({
146
+ status,
147
+ error,
148
+ retry: HOSTED_GUEST_RETRY_TRANSIENT,
149
+ message,
150
+ });
151
+ }
152
+
111
153
  /**
112
154
  * Classify deterministic authored protocol violations as non-retryable 422
113
155
  * admissions. Anything else returns `undefined` so callers fall through to
@@ -126,7 +168,7 @@ function nonRetryableRejection(error: unknown): AdmissionDispatch | undefined {
126
168
  return undefined;
127
169
  }
128
170
  return {
129
- response: errorResponse(
171
+ response: terminalHostedError(
130
172
  422,
131
173
  code,
132
174
  boundedMessage((error as Error).message)
@@ -134,6 +176,31 @@ function nonRetryableRejection(error: unknown): AdmissionDispatch | undefined {
134
176
  };
135
177
  }
136
178
 
179
+ /**
180
+ * Prefer the shared throw → HTTP mapper (guest network / connect stall /
181
+ * session busy / …) before collapsing into agent_admission_threw or
182
+ * background_dispatch_failed. Those agent codes otherwise hide typed
183
+ * transient failures that the outer handleRequest boundary never sees.
184
+ */
185
+ function mappedAdmissionFailure(error: unknown): AdmissionDispatch | undefined {
186
+ const rejected = nonRetryableRejection(error);
187
+ if (rejected !== undefined) {
188
+ return rejected;
189
+ }
190
+ const mapped = mapThrownRequestError(error);
191
+ if (mapped === undefined) {
192
+ return undefined;
193
+ }
194
+ return {
195
+ response: hostedGuestErrorResponse({
196
+ status: mapped.status,
197
+ error: mapped.code,
198
+ retry: mapped.retry,
199
+ message: boundedMessage(mapped.message),
200
+ }),
201
+ };
202
+ }
203
+
137
204
  /**
138
205
  * Run authored admission without creating a framework session. Authored
139
206
  * `task` callbacks execute as sessionless work; the first `send` is captured
@@ -150,10 +217,7 @@ export async function dispatchHostedAdmission(
150
217
  const adapter = getHostedAdmissionAdapter(input.definition);
151
218
  if (adapter === undefined || adapter.kind !== input.delivery.channelKind) {
152
219
  return {
153
- response: Response.json(
154
- { ok: false, error: "channel_kind_mismatch" },
155
- { status: 422 }
156
- ),
220
+ response: terminalHostedError(422, "channel_kind_mismatch"),
157
221
  };
158
222
  }
159
223
  // The admission window marker follows the async graph into task bodies so
@@ -161,6 +225,118 @@ export async function dispatchHostedAdmission(
161
225
  return runDuringHostedAdmission(() => runAdmission(input, adapter));
162
226
  }
163
227
 
228
+ /**
229
+ * Reserved reminder admission: parse the compact payload and invoke
230
+ * ReminderRunner.dispatch. Returns a standard hosted outcome (`task` /
231
+ * `skip`) and never opens the send-capture / model-session path here —
232
+ * prompt-form fires still follow up inside the runner.
233
+ */
234
+ async function dispatchHostedReminderAdmission(
235
+ input: {
236
+ fireReminder?(
237
+ reminderId: string,
238
+ expectedFireCount: number
239
+ ): Promise<{
240
+ reminderId: string;
241
+ outcome: "fired" | "noop";
242
+ reason?: string;
243
+ }>;
244
+ /**
245
+ * Architecture v2: execute an immutable CP descriptor and apply the
246
+ * structured outcome. Must not GET/PUT reminder lifecycle documents.
247
+ */
248
+ executeReminderDescriptor?(
249
+ descriptor: HostedReminderFireDescriptorPayload
250
+ ): Promise<{
251
+ reminderId: string;
252
+ outcome: "fired" | "noop";
253
+ reason?: string;
254
+ }>;
255
+ },
256
+ delivery: HostedAdmission
257
+ ): Promise<Response> {
258
+ const descriptor = parseHostedReminderFireDescriptorPayload(delivery.payload);
259
+ if (descriptor !== undefined) {
260
+ if (input.executeReminderDescriptor === undefined) {
261
+ return transientHostedError(
262
+ 503,
263
+ "reminder_dispatch_unavailable",
264
+ "This guest has no reminder CP executor wired for hosted admission."
265
+ );
266
+ }
267
+ try {
268
+ const result = await input.executeReminderDescriptor(descriptor);
269
+ const outcome = result.outcome === "noop" ? "skip" : "task";
270
+ return Response.json({
271
+ ok: true,
272
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
273
+ outcome,
274
+ });
275
+ } catch (error) {
276
+ if (error instanceof UnknownReminderError) {
277
+ return terminalHostedError(
278
+ 404,
279
+ "unknown_reminder",
280
+ boundedMessage(error.message)
281
+ );
282
+ }
283
+ if (error instanceof ReminderValidationError) {
284
+ return terminalHostedError(
285
+ 400,
286
+ "invalid_reminder",
287
+ boundedMessage(error.message)
288
+ );
289
+ }
290
+ // Transient CP apply/fetch failures must remain retryable.
291
+ throw error;
292
+ }
293
+ }
294
+
295
+ if (input.fireReminder === undefined) {
296
+ return transientHostedError(
297
+ 503,
298
+ "reminder_dispatch_unavailable",
299
+ "This guest has no reminder runner wired for hosted admission."
300
+ );
301
+ }
302
+ const payload = parseHostedReminderFirePayload(delivery.payload);
303
+ if (payload === undefined) {
304
+ return terminalHostedError(
305
+ 400,
306
+ "invalid_reminder_payload",
307
+ "Expected reminder descriptor or legacy payload { reminderId, fireCount }."
308
+ );
309
+ }
310
+ try {
311
+ const result = await input.fireReminder(
312
+ payload.reminderId,
313
+ payload.fireCount
314
+ );
315
+ const outcome = result.outcome === "noop" ? "skip" : "task";
316
+ return Response.json({
317
+ ok: true,
318
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
319
+ outcome,
320
+ });
321
+ } catch (error) {
322
+ if (error instanceof UnknownReminderError) {
323
+ return terminalHostedError(
324
+ 404,
325
+ "unknown_reminder",
326
+ boundedMessage(error.message)
327
+ );
328
+ }
329
+ if (error instanceof ReminderValidationError) {
330
+ return terminalHostedError(
331
+ 400,
332
+ "invalid_reminder",
333
+ boundedMessage(error.message)
334
+ );
335
+ }
336
+ throw error;
337
+ }
338
+ }
339
+
164
340
  async function runAdmission(
165
341
  input: DispatchInput,
166
342
  adapter: HostedAdmissionAdapter
@@ -184,23 +360,30 @@ async function runAdmission(
184
360
  let dispatched: Response;
185
361
  try {
186
362
  dispatched = await adapter.dispatch({
363
+ channelId: input.delivery.channelId,
187
364
  eventType: input.delivery.eventType,
188
365
  payload: input.delivery.payload,
189
366
  deliveryId: input.delivery.deliveryId,
190
367
  args,
191
368
  });
192
369
  } catch (error) {
193
- const rejected = nonRetryableRejection(error);
194
- if (rejected !== undefined) {
195
- return rejected;
370
+ const mapped = mappedAdmissionFailure(error);
371
+ if (mapped !== undefined) {
372
+ return mapped;
196
373
  }
197
- throw error;
374
+ return {
375
+ response: terminalHostedError(
376
+ 500,
377
+ "agent_admission_threw",
378
+ boundedMessage(error instanceof Error ? error.message : String(error))
379
+ ),
380
+ };
198
381
  }
199
382
  if (!dispatched.ok) {
200
383
  return {
201
- response: Response.json(
202
- { ok: false, error: "channel_dispatch_failed" },
203
- { status: dispatched.status >= 400 ? dispatched.status : 502 }
384
+ response: terminalHostedError(
385
+ dispatched.status >= 400 ? dispatched.status : 502,
386
+ "channel_dispatch_failed"
204
387
  ),
205
388
  };
206
389
  }
@@ -208,12 +391,12 @@ async function runAdmission(
208
391
  try {
209
392
  await Promise.all(background);
210
393
  } catch (error) {
211
- const rejected = nonRetryableRejection(error);
212
- if (rejected !== undefined) {
213
- return rejected;
394
+ const mapped = mappedAdmissionFailure(error);
395
+ if (mapped !== undefined) {
396
+ return mapped;
214
397
  }
215
398
  return {
216
- response: errorResponse(
399
+ response: terminalHostedError(
217
400
  503,
218
401
  "background_dispatch_failed",
219
402
  boundedMessage(error instanceof Error ? error.message : String(error))
@@ -240,10 +423,7 @@ async function runAdmission(
240
423
  const outcome = dispatchOutcome(dispatched);
241
424
  if (outcome === undefined || outcome === "send") {
242
425
  return {
243
- response: Response.json(
244
- { ok: false, error: "channel_outcome_missing" },
245
- { status: 502 }
246
- ),
426
+ response: terminalHostedError(502, "channel_outcome_missing"),
247
427
  };
248
428
  }
249
429
  return {
@@ -329,6 +509,30 @@ export function registerHostedDeliveryRoute(input: {
329
509
  channelId: string,
330
510
  sessionPublicId?: string
331
511
  ): ChannelHandlerArgs;
512
+ /**
513
+ * Reserved reminder admission: dispatch a hydrated ReminderRunner fire
514
+ * without authored channel admission. Returns the runner's outcome so the
515
+ * route can map fired → task and noop → skip.
516
+ */
517
+ fireReminder?(
518
+ reminderId: string,
519
+ expectedFireCount: number
520
+ ): Promise<{
521
+ reminderId: string;
522
+ outcome: "fired" | "noop";
523
+ reason?: string;
524
+ }>;
525
+ /**
526
+ * Architecture v2: execute an immutable CP fire descriptor and apply the
527
+ * structured outcome via the hosted ReminderControlPlane client.
528
+ */
529
+ executeReminderDescriptor?(
530
+ descriptor: HostedReminderFireDescriptorPayload
531
+ ): Promise<{
532
+ reminderId: string;
533
+ outcome: "fired" | "noop";
534
+ reason?: string;
535
+ }>;
332
536
  /**
333
537
  * Await the session's durable mirror (dispatch chain + storage queue)
334
538
  * before the execution reply: the control plane may park the pod the
@@ -400,7 +604,11 @@ export function registerHostedDeliveryRoute(input: {
400
604
  const consumed = consumeBoundSecrets();
401
605
  return consumed.ok
402
606
  ? undefined
403
- : errorResponse(503, consumed.code, boundedMessage(consumed.message));
607
+ : transientHostedError(
608
+ 503,
609
+ consumed.code,
610
+ boundedMessage(consumed.message)
611
+ );
404
612
  };
405
613
  const finishNetworkWait = async (
406
614
  phase: "admission" | "execution"
@@ -423,7 +631,7 @@ export function registerHostedDeliveryRoute(input: {
423
631
  : "Guest network is not ready for outbound requests.";
424
632
  return {
425
633
  timing,
426
- response: errorResponse(
634
+ response: transientHostedError(
427
635
  503,
428
636
  GUEST_NETWORK_UNAVAILABLE,
429
637
  boundedMessage(message)
@@ -483,7 +691,7 @@ export function registerHostedDeliveryRoute(input: {
483
691
  `[agent-sdk] hosted admission rejected: envelope failed to parse keys=${JSON.stringify(rawKeys)} hasManagedAutomation=${String(rawKeys.includes("managedAutomation"))}`
484
692
  );
485
693
  return finish(
486
- errorResponse(
694
+ terminalHostedError(
487
695
  400,
488
696
  "invalid_hosted_admission",
489
697
  "Expected a supported Agent SDK hosted-admission envelope."
@@ -494,12 +702,20 @@ export function registerHostedDeliveryRoute(input: {
494
702
  `[agent-sdk] hosted admission received deliveryId=${delivery.deliveryId} channelId=${delivery.channelId} channelKind=${delivery.channelKind} eventType=${delivery.eventType} sessionMode=${delivery.sessionMode} managedAutomation=${delivery.managedAutomation === undefined ? "<absent>" : `automationUuid=${delivery.managedAutomation.automationUuid} mcpServerNames=${String(delivery.managedAutomation.mcpServerNames.length)} slackChannels=${delivery.managedAutomation.slackChannels === undefined ? "<absent>" : JSON.stringify(delivery.managedAutomation.slackChannels)}`}`
495
703
  );
496
704
  recordHostedManagedAutomation(delivery);
705
+ if (isHostedReminderAdmission(delivery)) {
706
+ const network = await finishNetworkWait("admission");
707
+ guestNetwork = network.timing;
708
+ if (network.response !== undefined) {
709
+ return finish(network.response);
710
+ }
711
+ return finish(await dispatchHostedReminderAdmission(input, delivery));
712
+ }
497
713
  const channel = input.channels.find(
498
714
  (candidate) => candidate.id === delivery.channelId
499
715
  );
500
716
  if (channel === undefined) {
501
717
  return finish(
502
- errorResponse(
718
+ terminalHostedError(
503
719
  404,
504
720
  "channel_not_found",
505
721
  `No channel named "${delivery.channelId}" is mounted.`
@@ -556,7 +772,7 @@ export function registerHostedDeliveryRoute(input: {
556
772
  const execution = parseHostedExecution(await readJsonObject(request));
557
773
  if (execution === undefined) {
558
774
  return finish(
559
- errorResponse(
775
+ terminalHostedError(
560
776
  400,
561
777
  "invalid_hosted_execution",
562
778
  "Expected a supported Agent SDK hosted-execution envelope."
@@ -567,7 +783,7 @@ export function registerHostedDeliveryRoute(input: {
567
783
  const admitted = pending.get(execution.admissionToken);
568
784
  if (admitted === undefined) {
569
785
  return finish(
570
- errorResponse(
786
+ transientHostedError(
571
787
  409,
572
788
  "hosted_admission_unavailable",
573
789
  "The hosted admission token is missing or expired."
@@ -579,7 +795,7 @@ export function registerHostedDeliveryRoute(input: {
579
795
  admitted.sessionPublicId !== execution.sessionPublicId
580
796
  ) {
581
797
  return finish(
582
- errorResponse(
798
+ transientHostedError(
583
799
  409,
584
800
  "hosted_admission_session_mismatch",
585
801
  "The hosted admission token is already bound to another session."
@@ -616,8 +832,13 @@ export function registerHostedDeliveryRoute(input: {
616
832
  abortReason?:
617
833
  | ReturnType<typeof abortReasonFromTurnStatus>
618
834
  | "execute_throw";
835
+ failureCode?: string;
619
836
  error?: unknown;
620
837
  }): Promise<void> => {
838
+ const classification =
839
+ fields.failureCode === undefined
840
+ ? undefined
841
+ : hostedFailureClassification(fields.failureCode);
621
842
  await flushHostedExecutionRecord(sinks, {
622
843
  executionId,
623
844
  sessionPublicId: execution.sessionPublicId,
@@ -633,6 +854,8 @@ export function registerHostedDeliveryRoute(input: {
633
854
  ...(fields.abortReason === undefined
634
855
  ? {}
635
856
  : { abortReason: fields.abortReason }),
857
+ failureCode: fields.failureCode,
858
+ classification,
636
859
  ...(fields.error === undefined ? {} : { error: fields.error }),
637
860
  });
638
861
  };
@@ -669,24 +892,30 @@ export function registerHostedDeliveryRoute(input: {
669
892
  session.id,
670
893
  execution.sessionPublicId
671
894
  );
895
+ const hostedFailure =
896
+ outcome.status === "finished"
897
+ ? undefined
898
+ : hostedFailureForUnfinishedTurn(outcome);
672
899
  await writeDiag({
673
900
  sessionId: session.id,
674
901
  turnStatus: outcome.status,
675
902
  message: outcome.errorMessage,
676
903
  abortReason: abortReasonFromTurnStatus(
677
904
  outcome.status,
678
- outcome.errorMessage
905
+ outcome.cancellationReason
679
906
  ),
907
+ failureCode: hostedFailure?.error,
680
908
  });
681
- if (outcome.status !== "finished") {
682
- // waitForCompletion resolves (does not throw) on a quiet
683
- // Connect abort. Map that to guest_connect_stalled so TAS
684
- // retries the same pod. Real runner failures stay turn_failed.
909
+ if (hostedFailure !== undefined) {
685
910
  return {
686
911
  status: 503,
687
912
  body: {
688
913
  ok: false,
689
- error: hostedErrorForUnfinishedTurn(outcome.errorMessage),
914
+ error: hostedFailure.error,
915
+ retry: hostedFailure.retry,
916
+ classification: hostedFailureClassification(
917
+ hostedFailure.error
918
+ ),
690
919
  turnStatus: outcome.status,
691
920
  message: outcome.errorMessage,
692
921
  },
@@ -711,6 +940,7 @@ export function registerHostedDeliveryRoute(input: {
711
940
  turnStatus: "error",
712
941
  message: error instanceof Error ? error.message : String(error),
713
942
  abortReason: "execute_throw",
943
+ failureCode: "internal_error",
714
944
  error,
715
945
  });
716
946
  throw error;
@@ -739,16 +969,46 @@ function evictHostedSdkSessions(
739
969
  }
740
970
  }
741
971
 
742
- function hostedErrorForUnfinishedTurn(
743
- errorMessage: string | undefined
744
- ): typeof GUEST_CONNECT_STALLED | "turn_failed" {
972
+ const TRANSIENT_TURN_ERROR_CODES: ReadonlySet<string> = new Set([
973
+ "ABORT_ERR",
974
+ "UND_ERR_BODY_TIMEOUT",
975
+ "UND_ERR_HEADERS_TIMEOUT",
976
+ "canceled",
977
+ "unavailable",
978
+ "unknown",
979
+ ]);
980
+
981
+ function hostedFailureForUnfinishedTurn(outcome: TurnOutcome): {
982
+ error:
983
+ | typeof GUEST_CONNECT_STALLED
984
+ | "agent_dependency_failed"
985
+ | "turn_cancelled"
986
+ | "turn_failed";
987
+ retry: HostedGuestRetryDisposition;
988
+ } {
989
+ if (outcome.errorCode === "agent_dependency_failed") {
990
+ return {
991
+ error: "agent_dependency_failed",
992
+ retry: HOSTED_GUEST_RETRY_TERMINAL,
993
+ };
994
+ }
745
995
  if (
746
- errorMessage !== undefined &&
747
- isQuietGuestConnectStallMessage(errorMessage)
996
+ outcome.status === "error" &&
997
+ outcome.errorCode !== undefined &&
998
+ TRANSIENT_TURN_ERROR_CODES.has(outcome.errorCode)
748
999
  ) {
749
- return GUEST_CONNECT_STALLED;
1000
+ return {
1001
+ error: GUEST_CONNECT_STALLED,
1002
+ retry: HOSTED_GUEST_RETRY_TRANSIENT,
1003
+ };
1004
+ }
1005
+ if (outcome.status === "cancelled") {
1006
+ return {
1007
+ error: "turn_cancelled",
1008
+ retry: HOSTED_GUEST_RETRY_TERMINAL,
1009
+ };
750
1010
  }
751
- return "turn_failed";
1011
+ return { error: "turn_failed", retry: HOSTED_GUEST_RETRY_TERMINAL };
752
1012
  }
753
1013
 
754
1014
  async function afterHostedWork<T>(
@@ -8,7 +8,11 @@ import { createHash, randomBytes } from "node:crypto";
8
8
  import { mkdir, rename, unlink, writeFile } from "node:fs/promises";
9
9
  import { join } from "node:path";
10
10
 
11
- import { HOSTED_EXECUTION_DIAG_FILENAME } from "./hosted-delivery-protocol.js";
11
+ import {
12
+ HOSTED_EXECUTION_DIAG_FILENAME,
13
+ type HostedFailureClassification,
14
+ parseHostedFailureClassification,
15
+ } from "./hosted-delivery-protocol.js";
12
16
 
13
17
  export const HOSTED_EXECUTION_DIAG_VERSION = 1;
14
18
  /** Cap so a runaway message cannot fill the guest disk or the host log. */
@@ -57,6 +61,8 @@ export type HostedExecutionDiag = {
57
61
  signalAborted?: boolean;
58
62
  requestId?: string;
59
63
  abortReason?: HostedExecutionDiagAbortReason;
64
+ failureCode?: string;
65
+ classification?: HostedFailureClassification;
60
66
  };
61
67
 
62
68
  /** Written before the turn starts so a stalled execution still has a record. */
@@ -75,6 +81,8 @@ const DIAG_KEYS = new Set([
75
81
  "signalAborted",
76
82
  "requestId",
77
83
  "abortReason",
84
+ "failureCode",
85
+ "classification",
78
86
  ]);
79
87
 
80
88
  const ABORT_REASONS = new Set<HostedExecutionDiagAbortReason>([
@@ -137,13 +145,13 @@ export function hostedExecutionDiagPath(stateRoot: string): string {
137
145
 
138
146
  export function abortReasonFromTurnStatus(
139
147
  status: string,
140
- message: string | undefined
148
+ cancellationReason: "signal" | "runner" | undefined
141
149
  ): HostedExecutionDiagAbortReason | undefined {
142
150
  if (status === "finished") {
143
151
  return undefined;
144
152
  }
145
153
  if (status === "cancelled") {
146
- return message !== undefined && /abort/i.test(message)
154
+ return cancellationReason === "signal"
147
155
  ? "signal_abort"
148
156
  : "runner_cancelled";
149
157
  }
@@ -197,6 +205,14 @@ export function parseHostedExecutionDiag(
197
205
  HOSTED_ERROR_SNIPPET_MAX_CHARS
198
206
  );
199
207
  const requestId = boundedOptionalString(body.requestId, 128);
208
+ const failureCode = boundedOptionalString(body.failureCode, 64);
209
+ const classification =
210
+ body.classification === undefined
211
+ ? undefined
212
+ : parseHostedFailureClassification(body.classification);
213
+ if (body.classification !== undefined && classification === undefined) {
214
+ return undefined;
215
+ }
200
216
  const abortReason =
201
217
  body.abortReason === undefined
202
218
  ? undefined
@@ -226,6 +242,8 @@ export function parseHostedExecutionDiag(
226
242
  ...(body.signalAborted === true ? { signalAborted: true } : {}),
227
243
  ...(requestId === undefined ? {} : { requestId }),
228
244
  ...(abortReason === undefined ? {} : { abortReason }),
245
+ ...(failureCode === undefined ? {} : { failureCode }),
246
+ ...(classification === undefined ? {} : { classification }),
229
247
  };
230
248
  }
231
249
 
@@ -9,6 +9,7 @@
9
9
  * so TAS does not treat a previous delivery's terminal record as this one.
10
10
  */
11
11
 
12
+ import type { HostedFailureClassification } from "./hosted-delivery-protocol.js";
12
13
  import {
13
14
  type HostedExecutionDiagAbortReason,
14
15
  hostedErrorStackSnippet,
@@ -46,6 +47,8 @@ export type HostedExecutionFlushFields = {
46
47
  durationMs: number;
47
48
  message?: string;
48
49
  abortReason?: HostedExecutionDiagAbortReason;
50
+ failureCode?: string;
51
+ classification?: HostedFailureClassification;
49
52
  error?: unknown;
50
53
  };
51
54
 
@@ -75,12 +78,12 @@ export async function flushHostedExecutionRecord(
75
78
  durationMs: fields.durationMs,
76
79
  ...(message === undefined ? {} : { message }),
77
80
  ...(stack === undefined || stack.length === 0 ? {} : { stack }),
78
- ...(message !== undefined && /abort/i.test(message)
79
- ? { signalAborted: true }
80
- : {}),
81
+ signalAborted: fields.abortReason === "signal_abort" ? true : undefined,
81
82
  ...(fields.abortReason === undefined
82
83
  ? {}
83
84
  : { abortReason: fields.abortReason }),
85
+ failureCode: fields.failureCode,
86
+ classification: fields.classification,
84
87
  });
85
88
  }
86
89
  if (sinks.persistSessionRun !== undefined) {