@cursor/july 0.1.94 → 0.1.96

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 (332) hide show
  1. package/AGENTS.md +3 -4
  2. package/dist/channels/deployments/types.d.ts +1 -1
  3. package/dist/channels/deployments/types.d.ts.map +1 -1
  4. package/dist/channels/deployments/types.js +1 -0
  5. package/dist/channels/github/github-channel.d.ts.map +1 -1
  6. package/dist/channels/github/github-channel.js +14 -2
  7. package/dist/channels/github/types.d.ts +18 -3
  8. package/dist/channels/github/types.d.ts.map +1 -1
  9. package/dist/channels/origin/api.d.ts +59 -13
  10. package/dist/channels/origin/api.d.ts.map +1 -1
  11. package/dist/channels/origin/api.js +168 -27
  12. package/dist/channels/origin/binding.d.ts +2 -2
  13. package/dist/channels/origin/checks.d.ts +6 -6
  14. package/dist/channels/origin/checks.js +6 -6
  15. package/dist/channels/origin/cursor-account.d.ts +5 -3
  16. package/dist/channels/origin/cursor-account.d.ts.map +1 -1
  17. package/dist/channels/origin/cursor-account.js +5 -3
  18. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  19. package/dist/channels/origin/origin-channel.js +11 -3
  20. package/dist/channels/origin/origin-webhook.d.ts +11 -1
  21. package/dist/channels/origin/origin-webhook.d.ts.map +1 -1
  22. package/dist/channels/origin/origin-webhook.js +23 -3
  23. package/dist/channels/origin/types.d.ts +8 -0
  24. package/dist/channels/origin/types.d.ts.map +1 -1
  25. package/dist/channels/slack/api.d.ts +9 -0
  26. package/dist/channels/slack/api.d.ts.map +1 -1
  27. package/dist/channels/slack/api.js +36 -5
  28. package/dist/channels/slack/defaults.d.ts.map +1 -1
  29. package/dist/channels/slack/defaults.js +17 -46
  30. package/dist/channels/slack/dispatch.d.ts +7 -1
  31. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  32. package/dist/channels/slack/dispatch.js +47 -23
  33. package/dist/channels/slack/inbound.d.ts +8 -0
  34. package/dist/channels/slack/inbound.d.ts.map +1 -1
  35. package/dist/channels/slack/inbound.js +32 -0
  36. package/dist/channels/slack/live-delivery.d.ts +26 -29
  37. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  38. package/dist/channels/slack/live-delivery.js +172 -73
  39. package/dist/channels/slack/manifest.d.ts.map +1 -1
  40. package/dist/channels/slack/manifest.js +5 -1
  41. package/dist/channels/slack/nudge-carrier.d.ts +2 -0
  42. package/dist/channels/slack/nudge-carrier.d.ts.map +1 -1
  43. package/dist/channels/slack/nudge-carrier.js +48 -1
  44. package/dist/channels/slack/pr-ref.d.ts +7 -1
  45. package/dist/channels/slack/pr-ref.d.ts.map +1 -1
  46. package/dist/channels/slack/pr-ref.js +42 -23
  47. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  48. package/dist/channels/slack/slack-channel.js +2 -2
  49. package/dist/docs/404.html +2 -2
  50. package/dist/docs/ab.html +4 -4
  51. package/dist/docs/assets/{app.CFDEas4I.js → app.jXleCmOc.js} +1 -1
  52. package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +1 -0
  53. package/dist/docs/assets/chunks/{VPLocalSearchBox.B1IIYpYS.js → VPLocalSearchBox.8LhyglIT.js} +1 -1
  54. package/dist/docs/assets/chunks/{theme.Ct4NSiLm.js → theme.9ged-pr2.js} +2 -2
  55. package/dist/docs/assets/index.md.CI93Ltlb.js +5 -0
  56. package/dist/docs/assets/{index.md.DRakGHFe.lean.js → index.md.CI93Ltlb.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_cli.md.Cw6_ICYG.js → reference_cli.md.CCnG-nJx.js} +4 -2
  58. package/dist/docs/assets/{reference_cli.md.Cw6_ICYG.lean.js → reference_cli.md.CCnG-nJx.lean.js} +1 -1
  59. package/dist/docs/assets/{reference_skills.md.8son6Hjm.js → reference_skills.md.BFW9retM.js} +3 -3
  60. package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.js → templates_agentic-owners.md.BZSH4N9z.js} +1 -1
  61. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +2 -0
  62. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +1 -0
  63. package/dist/docs/assets/{templates_demo.md.DhFcWN6j.js → templates_demo.md.BeQX9V3H.js} +1 -1
  64. package/dist/docs/assets/{templates_pr-autofixer.md.DU7dQpor.js → templates_pr-autofixer.md.x5zl6-GT.js} +2 -2
  65. package/dist/docs/assets/{templates_pr-autofixer.md.DU7dQpor.lean.js → templates_pr-autofixer.md.x5zl6-GT.lean.js} +1 -1
  66. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +4 -0
  67. package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +1 -0
  68. package/dist/docs/assets/{templates_security-reviewer.md.CTa7u_l1.js → templates_security-reviewer.md.lshxbCLK.js} +2 -2
  69. package/dist/docs/assets/{templates_security-reviewer.md.CTa7u_l1.lean.js → templates_security-reviewer.md.lshxbCLK.lean.js} +1 -1
  70. package/dist/docs/assets/{templates_triage.md.CVlpctKS.js → templates_triage.md.Co4UNzkZ.js} +3 -3
  71. package/dist/docs/assets/{templates_triage.md.CVlpctKS.lean.js → templates_triage.md.Co4UNzkZ.lean.js} +1 -1
  72. package/dist/docs/building-with-agents.html +4 -4
  73. package/dist/docs/concepts.html +4 -4
  74. package/dist/docs/deployment.html +4 -4
  75. package/dist/docs/evals.html +4 -4
  76. package/dist/docs/guides/agent-to-agent.html +4 -4
  77. package/dist/docs/guides/cloud-runtime.html +4 -4
  78. package/dist/docs/guides/convert-automation.html +4 -4
  79. package/dist/docs/guides/github.html +4 -4
  80. package/dist/docs/guides/human-in-the-loop.html +4 -4
  81. package/dist/docs/guides/mcp-oauth.html +4 -4
  82. package/dist/docs/guides/opentelemetry.html +4 -4
  83. package/dist/docs/guides/slack.html +4 -4
  84. package/dist/docs/guides/webhooks.html +4 -4
  85. package/dist/docs/hashmap.json +1 -1
  86. package/dist/docs/hillclimbing.html +4 -4
  87. package/dist/docs/index.html +6 -6
  88. package/dist/docs/index.md +5 -1
  89. package/dist/docs/llms-full.txt +189 -26
  90. package/dist/docs/llms.txt +2 -0
  91. package/dist/docs/quickstart.html +4 -4
  92. package/dist/docs/reference/agent-config.html +4 -4
  93. package/dist/docs/reference/artifacts.html +4 -4
  94. package/dist/docs/reference/channels.html +4 -4
  95. package/dist/docs/reference/cli.html +8 -6
  96. package/dist/docs/reference/cli.md +4 -1
  97. package/dist/docs/reference/connections.html +4 -4
  98. package/dist/docs/reference/hooks.html +4 -4
  99. package/dist/docs/reference/http-api.html +4 -4
  100. package/dist/docs/reference/instructions.html +4 -4
  101. package/dist/docs/reference/playground.html +4 -4
  102. package/dist/docs/reference/project-layout.html +4 -4
  103. package/dist/docs/reference/prompt.html +4 -4
  104. package/dist/docs/reference/schedules.html +4 -4
  105. package/dist/docs/reference/sessions.html +4 -4
  106. package/dist/docs/reference/skills.html +7 -7
  107. package/dist/docs/reference/subagents.html +4 -4
  108. package/dist/docs/reference/tools.html +4 -4
  109. package/dist/docs/scaffolding-agents.html +4 -4
  110. package/dist/docs/storage.html +4 -4
  111. package/dist/docs/templates/agentic-owners.html +7 -7
  112. package/dist/docs/templates/agentic-owners.md +1 -1
  113. package/dist/docs/templates/code-wiki.html +28 -0
  114. package/dist/docs/templates/code-wiki.md +91 -0
  115. package/dist/docs/templates/demo.html +6 -6
  116. package/dist/docs/templates/demo.md +3 -2
  117. package/dist/docs/templates/pr-autofixer.html +6 -6
  118. package/dist/docs/templates/pr-autofixer.md +7 -13
  119. package/dist/docs/templates/security-help.html +30 -0
  120. package/dist/docs/templates/security-help.md +65 -0
  121. package/dist/docs/templates/security-reviewer.html +6 -6
  122. package/dist/docs/templates/security-reviewer.md +1 -2
  123. package/dist/docs/templates/triage.html +7 -7
  124. package/dist/docs/templates/triage.md +2 -6
  125. package/dist/docs/troubleshooting.html +4 -4
  126. package/dist/files-backends/cursor-hosted.d.ts +26 -0
  127. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  128. package/dist/files-backends/cursor-hosted.js +32 -4
  129. package/dist/files.d.ts +2 -0
  130. package/dist/files.d.ts.map +1 -1
  131. package/dist/files.js +5 -0
  132. package/dist/internal/advertise-tools.d.ts +2 -0
  133. package/dist/internal/advertise-tools.d.ts.map +1 -1
  134. package/dist/internal/advertise-tools.js +15 -1
  135. package/dist/internal/bounded.d.ts +7 -0
  136. package/dist/internal/bounded.d.ts.map +1 -0
  137. package/dist/internal/bounded.js +32 -0
  138. package/dist/internal/cli-deploy.d.ts.map +1 -1
  139. package/dist/internal/cli-deploy.js +142 -7
  140. package/dist/internal/conversation-mirror.d.ts +85 -0
  141. package/dist/internal/conversation-mirror.d.ts.map +1 -0
  142. package/dist/internal/conversation-mirror.js +312 -0
  143. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  144. package/dist/internal/cursor/backend-client.js +22 -48
  145. package/dist/internal/cursor/session-token.d.ts +45 -0
  146. package/dist/internal/cursor/session-token.d.ts.map +1 -0
  147. package/dist/internal/cursor/session-token.js +99 -0
  148. package/dist/internal/cursor-agent-template.d.ts +1 -1
  149. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  150. package/dist/internal/cursor-agent-template.js +1 -0
  151. package/dist/internal/deferred-channel-session.d.ts +20 -0
  152. package/dist/internal/deferred-channel-session.d.ts.map +1 -0
  153. package/dist/internal/deferred-channel-session.js +62 -0
  154. package/dist/internal/deploy-client.d.ts +13 -1
  155. package/dist/internal/deploy-client.d.ts.map +1 -1
  156. package/dist/internal/deploy-client.js +11 -1
  157. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  158. package/dist/internal/deploy-manifest.js +11 -5
  159. package/dist/internal/discovery.d.ts.map +1 -1
  160. package/dist/internal/discovery.js +22 -2
  161. package/dist/internal/framework-file-storage.d.ts +61 -0
  162. package/dist/internal/framework-file-storage.d.ts.map +1 -0
  163. package/dist/internal/framework-file-storage.js +204 -0
  164. package/dist/internal/framework-storage-selection.d.ts +38 -16
  165. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  166. package/dist/internal/framework-storage-selection.js +78 -17
  167. package/dist/internal/hosted-admission-context.d.ts +20 -0
  168. package/dist/internal/hosted-admission-context.d.ts.map +1 -0
  169. package/dist/internal/hosted-admission-context.js +31 -0
  170. package/dist/internal/hosted-delivery-protocol.d.ts +5 -0
  171. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  172. package/dist/internal/hosted-delivery-protocol.js +33 -1
  173. package/dist/internal/hosted-delivery.d.ts +11 -2
  174. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  175. package/dist/internal/hosted-delivery.js +79 -35
  176. package/dist/internal/hosted-managed-automation.d.ts +30 -0
  177. package/dist/internal/hosted-managed-automation.d.ts.map +1 -0
  178. package/dist/internal/hosted-managed-automation.js +58 -0
  179. package/dist/internal/init-project.d.ts.map +1 -1
  180. package/dist/internal/init-project.js +2 -0
  181. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  182. package/dist/internal/install-cursor-skills.js +1 -3
  183. package/dist/internal/managed-delivery.d.ts +80 -0
  184. package/dist/internal/managed-delivery.d.ts.map +1 -0
  185. package/dist/internal/managed-delivery.js +86 -0
  186. package/dist/internal/review-comments.d.ts.map +1 -1
  187. package/dist/internal/review-comments.js +10 -98
  188. package/dist/internal/runtime-dispatch-runner.d.ts +5 -1
  189. package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
  190. package/dist/internal/runtime-dispatch-runner.js +7 -0
  191. package/dist/internal/scm/pr-url.d.ts +14 -0
  192. package/dist/internal/scm/pr-url.d.ts.map +1 -0
  193. package/dist/internal/scm/pr-url.js +65 -0
  194. package/dist/internal/sdk-runner.d.ts +25 -0
  195. package/dist/internal/sdk-runner.d.ts.map +1 -1
  196. package/dist/internal/sdk-runner.js +70 -0
  197. package/dist/internal/server.d.ts.map +1 -1
  198. package/dist/internal/server.js +11 -2
  199. package/dist/internal/session-engine.d.ts +13 -0
  200. package/dist/internal/session-engine.d.ts.map +1 -1
  201. package/dist/internal/session-engine.js +71 -3
  202. package/dist/internal/steering.d.ts +15 -0
  203. package/dist/internal/steering.d.ts.map +1 -0
  204. package/dist/internal/steering.js +18 -0
  205. package/dist/playground/assets/index-B1DDvBeC.css +1 -0
  206. package/dist/playground/assets/{index-B3JCyigB.js → index-Cx9CclK_.js} +47 -47
  207. package/dist/playground/index.html +2 -2
  208. package/dist/storage-backends/cursor-hosted.d.ts +8 -0
  209. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  210. package/dist/storage-backends/cursor-hosted.js +4 -3
  211. package/dist/types.d.ts +2 -1
  212. package/dist/types.d.ts.map +1 -1
  213. package/docs/README.md +5 -1
  214. package/docs/reference/cli.md +4 -1
  215. package/docs/templates/agentic-owners.md +1 -1
  216. package/docs/templates/code-wiki.md +96 -0
  217. package/docs/templates/demo.md +3 -2
  218. package/docs/templates/pr-autofixer.md +7 -13
  219. package/docs/templates/security-help.md +70 -0
  220. package/docs/templates/security-reviewer.md +1 -2
  221. package/docs/templates/triage.md +2 -6
  222. package/package.json +2 -2
  223. package/skills/ab/SKILL.md +13 -97
  224. package/skills/create-agent/SKILL.md +123 -223
  225. package/skills/debug/SKILL.md +34 -68
  226. package/skills/evals/SKILL.md +55 -180
  227. package/skills/framework-map/SKILL.md +83 -145
  228. package/skills/github/SKILL.md +53 -111
  229. package/skills/hillclimb/SKILL.md +40 -163
  230. package/skills/mcp-auth/SKILL.md +48 -107
  231. package/skills/otel/SKILL.md +22 -68
  232. package/skills/setup-slack/SKILL.md +77 -208
  233. package/src/channels/deployments/types.ts +1 -0
  234. package/src/channels/github/github-channel.ts +23 -8
  235. package/src/channels/github/types.ts +19 -2
  236. package/src/channels/origin/api.ts +242 -30
  237. package/src/channels/origin/binding.ts +2 -2
  238. package/src/channels/origin/checks.ts +6 -6
  239. package/src/channels/origin/cursor-account.ts +5 -3
  240. package/src/channels/origin/origin-channel.ts +13 -1
  241. package/src/channels/origin/origin-webhook.ts +27 -3
  242. package/src/channels/origin/types.ts +8 -0
  243. package/src/channels/slack/api.ts +41 -5
  244. package/src/channels/slack/defaults.ts +15 -49
  245. package/src/channels/slack/dispatch.ts +56 -22
  246. package/src/channels/slack/inbound.ts +43 -0
  247. package/src/channels/slack/live-delivery.ts +235 -114
  248. package/src/channels/slack/manifest.ts +5 -1
  249. package/src/channels/slack/nudge-carrier.ts +48 -1
  250. package/src/channels/slack/pr-ref.ts +56 -25
  251. package/src/channels/slack/slack-channel.ts +2 -0
  252. package/src/files-backends/cursor-hosted.ts +41 -2
  253. package/src/files.ts +11 -0
  254. package/src/internal/advertise-tools.ts +18 -2
  255. package/src/internal/bounded.ts +28 -0
  256. package/src/internal/cli-deploy.ts +183 -7
  257. package/src/internal/conversation-mirror.ts +406 -0
  258. package/src/internal/cursor/backend-client.ts +34 -58
  259. package/src/internal/cursor/session-token.ts +115 -0
  260. package/src/internal/cursor-agent-template.ts +1 -0
  261. package/src/internal/deferred-channel-session.ts +61 -0
  262. package/src/internal/deploy-client.ts +24 -1
  263. package/src/internal/deploy-manifest.ts +10 -5
  264. package/src/internal/discovery.ts +25 -2
  265. package/src/internal/framework-file-storage.ts +222 -0
  266. package/src/internal/framework-storage-selection.ts +101 -19
  267. package/src/internal/hosted-admission-context.ts +37 -0
  268. package/src/internal/hosted-delivery-protocol.ts +44 -1
  269. package/src/internal/hosted-delivery.ts +105 -40
  270. package/src/internal/hosted-managed-automation.ts +72 -0
  271. package/src/internal/init-project.ts +2 -0
  272. package/src/internal/install-cursor-skills.ts +1 -4
  273. package/src/internal/managed-delivery.ts +125 -0
  274. package/src/internal/review-comments.ts +10 -113
  275. package/src/internal/runtime-dispatch-runner.ts +10 -0
  276. package/src/internal/scm/pr-url.ts +95 -0
  277. package/src/internal/sdk-runner.ts +103 -0
  278. package/src/internal/server.ts +12 -0
  279. package/src/internal/session-engine.ts +76 -4
  280. package/src/internal/steering.ts +17 -0
  281. package/src/storage-backends/cursor-hosted.ts +10 -1
  282. package/src/types.ts +2 -1
  283. package/templates/agentic-owners/README.md +1 -1
  284. package/templates/agentic-owners/agent/agent.ts +0 -10
  285. package/templates/agentic-owners/agent/channels/github.ts +5 -14
  286. package/templates/agentic-owners/agent/lib/config.ts +0 -8
  287. package/templates/agentic-owners/agent/lib/review.ts +2 -15
  288. package/templates/agentic-owners/agent/tools/record_review.ts +2 -4
  289. package/templates/code-wiki/README.md +34 -0
  290. package/templates/code-wiki/agent/agent.ts +8 -0
  291. package/templates/code-wiki/agent/channels/github.ts +144 -0
  292. package/templates/code-wiki/agent/instructions.md +39 -0
  293. package/templates/code-wiki/agent/lib/repos.ts +5 -0
  294. package/templates/code-wiki/agent/lib/wiki.ts +22 -0
  295. package/templates/code-wiki/agent/tools/apply_wiki.ts +219 -0
  296. package/templates/code-wiki/evals/evals.config.ts +5 -0
  297. package/templates/code-wiki/evals/wiki.eval.ts +132 -0
  298. package/templates/code-wiki/init.json +25 -0
  299. package/templates/code-wiki/package.json +18 -0
  300. package/templates/code-wiki/tsconfig.json +12 -0
  301. package/templates/demo/agent/agent.ts +0 -10
  302. package/templates/pr-autofixer/README.md +0 -2
  303. package/templates/pr-autofixer/agent/agent.ts +0 -11
  304. package/templates/pr-autofixer/agent/channels/slack.ts +0 -7
  305. package/templates/pr-autofixer/agent/lib/pr-state.ts +5 -17
  306. package/templates/pr-autofixer/agent/lib/repos.ts +0 -1
  307. package/templates/security-help/README.md +2 -2
  308. package/templates/security-help/agent/agent.ts +1 -2
  309. package/templates/security-help/agent/channels/slack.ts +0 -3
  310. package/templates/security-help/agent/instructions.md +9 -10
  311. package/templates/security-help/agent/skills/access-request.md +1 -1
  312. package/templates/security-help/agent/skills/faq.md +31 -0
  313. package/templates/security-help/agent/skills/security-playbooks.md +1 -1
  314. package/templates/security-help/package.json +1 -2
  315. package/templates/security-reviewer/agent/agent.ts +0 -10
  316. package/templates/triage/agent/agent.ts +0 -10
  317. package/templates/triage/agent/channels/queue.ts +1 -1
  318. package/templates/triage/agent/channels/webhook.ts +1 -3
  319. package/dist/docs/assets/chunks/@localSearchIndexroot.DU3U2Ij2.js +0 -1
  320. package/dist/docs/assets/index.md.DRakGHFe.js +0 -5
  321. package/dist/internal/deployment-scm-event-stream.d.ts +0 -116
  322. package/dist/internal/deployment-scm-event-stream.d.ts.map +0 -1
  323. package/dist/internal/deployment-scm-event-stream.js +0 -474
  324. package/dist/playground/assets/index-D9N7-q97.css +0 -1
  325. package/src/internal/deployment-scm-event-stream.ts +0 -593
  326. package/templates/security-help/agent/knowledge/faq/approvals.md +0 -5
  327. package/templates/security-help/agent/knowledge/faq/channels.md +0 -6
  328. package/templates/security-help/agent/knowledge/faq/phishing.md +0 -10
  329. package/templates/security-help/agent/skills/security-first-pass.md +0 -15
  330. /package/dist/docs/assets/{reference_skills.md.8son6Hjm.lean.js → reference_skills.md.BFW9retM.lean.js} +0 -0
  331. /package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.lean.js → templates_agentic-owners.md.BZSH4N9z.lean.js} +0 -0
  332. /package/dist/docs/assets/{templates_demo.md.DhFcWN6j.lean.js → templates_demo.md.BeQX9V3H.lean.js} +0 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Framework-level file storage for v2 hosted engines.
3
+ *
4
+ * Hosted deployments carry two file stores with different audiences:
5
+ *
6
+ * - the **user-level** store (`AGENT_SERVE_STORE_SOURCE_ID`) holds
7
+ * author-facing bytes — `ctx.host.files`, skills, memory, artifacts — and
8
+ * is browsable from the dashboard and mountable on cloud-runtime VMs;
9
+ * - the **framework-level** store (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`)
10
+ * holds engine-owned session state — session records, event transcripts,
11
+ * the continuation index, and the SDK conversation mirror — and is never
12
+ * exposed to authors or models.
13
+ *
14
+ * This module puts framework session state on the framework store. The
15
+ * {@link storageKeys} scheme was designed for exactly this: keys are a
16
+ * stable versioned contract that sinks may route on, so
17
+ * {@link composeFrameworkStorage} splits one {@link StorageConfig} by key
18
+ * kind — `session` / `session-events` / `continuation` go to the framework
19
+ * file store (file-shaped; the store accepts values up to 64 MiB per
20
+ * object without chunking, versus the KV proxy's 1 MiB row cap), while
21
+ * author `kv`, eval runs, A/B samples, and conditional writes stay on the
22
+ * control-plane KV proxy (the dashboard reads them there, and CAS needs a
23
+ * database).
24
+ *
25
+ * v2 only, by construction: the composite is selected in
26
+ * framework-storage-selection.ts, which v1 never reaches with a
27
+ * platform-selected definition.
28
+ */
29
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
30
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
31
+ return new (P || (P = Promise))(function (resolve, reject) {
32
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
33
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
34
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
35
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
36
+ });
37
+ };
38
+ import { STORAGE_KEY_ROOT } from "../storage-protocol.js";
39
+ import { mapBounded } from "./bounded.js";
40
+ /**
41
+ * Key kinds (`agentkit/v1/{agent}/{kind}/…`) that live on the framework
42
+ * file store. Everything else stays on the KV sink.
43
+ */
44
+ const FRAMEWORK_FILE_KINDS = new Set([
45
+ "session",
46
+ "session-events",
47
+ "continuation",
48
+ ]);
49
+ /**
50
+ * Whether a framework-minted key (or list prefix) belongs on the framework
51
+ * file store. Prefixes used by the coordinator are always at least
52
+ * kind-scoped (`…/{agent}/session/`), so a prefix routes wholly to one side.
53
+ */
54
+ export function isFrameworkFileKey(key) {
55
+ if (!key.startsWith(`${STORAGE_KEY_ROOT}/`)) {
56
+ return false;
57
+ }
58
+ const rest = key.slice(STORAGE_KEY_ROOT.length + 1);
59
+ const agentEnd = rest.indexOf("/");
60
+ if (agentEnd === -1) {
61
+ return false;
62
+ }
63
+ const afterAgent = rest.slice(agentEnd + 1);
64
+ const kindEnd = afterAgent.indexOf("/");
65
+ const kind = kindEnd === -1 ? afterAgent : afterAgent.slice(0, kindEnd);
66
+ return FRAMEWORK_FILE_KINDS.has(kind);
67
+ }
68
+ /**
69
+ * Adapt a {@link FileSink} to the `defineStorage` KV core. Storage keys are
70
+ * framework-minted (URI-encoded, length-bounded segments — see
71
+ * {@link storageKeys}), so they are used as file keys verbatim; values are
72
+ * stored as JSON bytes. Parse failures throw: on the lazy-restore path a
73
+ * corrupt document must fail the follow-up rather than read as a miss, and
74
+ * the startup bulk restore already logs-and-skips a throwing `list`.
75
+ */
76
+ /** Parallel per-key reads backing `list` (each is presign + object GET). */
77
+ const LIST_READ_CONCURRENCY = 8;
78
+ /**
79
+ * A storage key whose path the file store cannot represent (an empty, `.`,
80
+ * or `..` segment — possible only through caller-controlled segments such
81
+ * as continuation tokens or a caller-supplied session id). Such an object
82
+ * can never exist in the store, so reads are a definitive miss rather than
83
+ * a per-request 400 that the lazy-restore path would propagate forever.
84
+ */
85
+ function isUnrepresentableFileKey(key) {
86
+ return key
87
+ .split("/")
88
+ .some((segment) => segment === "" || segment === "." || segment === "..");
89
+ }
90
+ export function fileSinkStorageCore(sink) {
91
+ return {
92
+ put(key, value) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ if (isUnrepresentableFileKey(key)) {
95
+ // Loud rather than silent: the coordinator logs and drops failed
96
+ // mirror writes (at-most-once), and awaited callers must not
97
+ // believe an impossible write landed.
98
+ throw new Error(`framework file storage: key "${key}" has a path segment the store cannot represent`);
99
+ }
100
+ yield sink.put(key, new TextEncoder().encode(JSON.stringify(value)));
101
+ });
102
+ },
103
+ get(key) {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ if (isUnrepresentableFileKey(key)) {
106
+ return undefined;
107
+ }
108
+ const body = yield sink.get(key);
109
+ if (body === undefined) {
110
+ return undefined;
111
+ }
112
+ return decodeDocument(key, body instanceof Uint8Array ? body : body.body);
113
+ });
114
+ },
115
+ delete(key) {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ if (isUnrepresentableFileKey(key)) {
118
+ return;
119
+ }
120
+ yield sink.delete(key);
121
+ });
122
+ },
123
+ list(prefix) {
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ const entries = yield sink.list(prefix);
126
+ // FileSink.list returns metadata only, so each value is its own
127
+ // read; bound the fan-out — a bulk read here sits on restore paths.
128
+ const bodies = yield mapBounded(entries, LIST_READ_CONCURRENCY, (entry) => sink.get(entry.key));
129
+ const out = [];
130
+ for (let index = 0; index < entries.length; index += 1) {
131
+ const entry = entries[index];
132
+ const body = bodies[index];
133
+ if (entry === undefined || body === undefined) {
134
+ // Deleted between list and read; a miss is not corruption.
135
+ continue;
136
+ }
137
+ out.push({
138
+ key: entry.key,
139
+ value: decodeDocument(entry.key, body instanceof Uint8Array ? body : body.body),
140
+ });
141
+ }
142
+ return out;
143
+ });
144
+ },
145
+ };
146
+ }
147
+ function decodeDocument(key, bytes) {
148
+ try {
149
+ return JSON.parse(new TextDecoder().decode(bytes));
150
+ }
151
+ catch (error) {
152
+ throw new Error(`framework file storage: stored document at "${key}" is not JSON (${error instanceof Error ? error.message : String(error)})`);
153
+ }
154
+ }
155
+ /**
156
+ * Split one storage core by key kind: framework session state to `files`,
157
+ * everything else to `kv`. Spread over the KV backend when building the
158
+ * full definition so its `evals` / `abs` groups (and the cursor-hosted
159
+ * marker) ride along untouched; wrap the KV `cas` group with
160
+ * {@link frameworkGuardedCas} rather than spreading it as-is.
161
+ */
162
+ export function composeFrameworkStorage(input) {
163
+ const route = (key) => isFrameworkFileKey(key) ? input.files : input.kv;
164
+ return {
165
+ put: (key, value, ctx) => route(key).put(key, value, ctx),
166
+ get: (key, ctx) => route(key).get(key, ctx),
167
+ delete: (key, ctx) => route(key).delete(key, ctx),
168
+ list: (prefix, ctx) => route(prefix).list(prefix, ctx),
169
+ };
170
+ }
171
+ /**
172
+ * The KV backend's conditional writes, refusing framework-file keys.
173
+ *
174
+ * CAS runs on the KV proxy (a database row version); the plain core routes
175
+ * framework session state to the file store. A future coordination path
176
+ * that CASes a `session/` or `continuation/` key would otherwise read and
177
+ * write a different store than the plain path — silent split-brain. Fail
178
+ * loudly instead; nothing in the package CASes those kinds today.
179
+ */
180
+ export function frameworkGuardedCas(cas) {
181
+ const refuse = (key) => {
182
+ if (isFrameworkFileKey(key)) {
183
+ throw new Error(`framework file storage: conditional writes are KV-only, but "${key}" routes to the framework file store`);
184
+ }
185
+ };
186
+ return {
187
+ getWithVersion: (key, ctx) => {
188
+ refuse(key);
189
+ return cas.getWithVersion(key, ctx);
190
+ },
191
+ putIfAbsent: (key, value, ctx) => {
192
+ refuse(key);
193
+ return cas.putIfAbsent(key, value, ctx);
194
+ },
195
+ putIfVersion: (key, value, expectedVersion, ctx) => {
196
+ refuse(key);
197
+ return cas.putIfVersion(key, value, expectedVersion, ctx);
198
+ },
199
+ listKeys: (prefix, ctx) => {
200
+ refuse(prefix);
201
+ return cas.listKeys(prefix, ctx);
202
+ },
203
+ };
204
+ }
@@ -2,36 +2,58 @@
2
2
  * Which backend framework session state is mirrored to.
3
3
  *
4
4
  * Framework state — session records, event chunks, the continuation index —
5
- * is how a session outlives the process that served it. Today that mirror
6
- * exists only when the agent author wrote `agent/storage.ts`, which makes
7
- * platform durability an agent-level decision: of the first-party agents,
8
- * some choose `cursorHostedStorage()` and some choose `fileKv()` (pod-local
9
- * disk, lost on pod replacement), and one selects between them at runtime by
10
- * reading the deployment-id environment variable itself.
5
+ * is how a session outlives the process that served it. On architecture v1
6
+ * that mirror exists only when the agent author wrote `agent/storage.ts`,
7
+ * which makes platform durability an agent-level decision: of the
8
+ * first-party agents, some choose `cursorHostedStorage()` and some choose
9
+ * `fileKv()` (pod-local disk, lost on pod replacement), and one selects
10
+ * between them at runtime by reading the deployment-id environment variable
11
+ * itself.
11
12
  *
12
- * That selection is a hosting-mode question, not an authoring question, and
13
- * this module is where it will move. It deliberately reproduces today's
14
- * behavior exactly for now authored definition or nothing so the change
15
- * that makes framework durability automatic is a change to
16
- * {@link selectFrameworkStorageDefinition} alone, reviewable on its own and
17
- * revertable without touching the engine.
13
+ * That selection is a hosting-mode question, not an authoring question.
14
+ * Architecture v2 moves it here: `agent/storage.ts` is rejected at
15
+ * discovery (error diagnostic, so serve and deploy fail early), and the
16
+ * platform picks the default
17
+ *
18
+ * - **Cursor-managed hosting** (the deployment-generation environment
19
+ * variable is set, same signal that registers `GET /v1/manifest`):
20
+ * the Cursor-hosted backend. When the deployment carries a
21
+ * **framework-level file store**
22
+ * (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`), session records, event
23
+ * transcripts, and the continuation index live there — file-shaped state
24
+ * on file storage, apart from the author-facing user store — while
25
+ * `host.kv`, eval runs, A/B samples, and conditional writes stay on the
26
+ * control-plane KV proxy (see framework-file-storage.ts). Without one
27
+ * (a deploy predating framework-store provisioning), everything goes to
28
+ * the KV proxy as before. The API key resolves through the full
29
+ * credential chain on every call because hosted freeze snapshots listen
30
+ * unsigned and the binder drops the key file after restore.
31
+ * - **Self-hosted**: no mirror. `--state-root` is the durable copy, which
32
+ * is correct when the operator owns the disk.
33
+ *
34
+ * v1 keeps the authored definition (or nothing) so existing deployments are
35
+ * untouched while they run.
18
36
  *
19
37
  * Local disk is not part of this decision. `<stateRoot>/sessions/<id>/`
20
38
  * already holds `session.json` and `events.ndjson` unconditionally, through
21
39
  * the session store; what this selects is the durable mirror *beyond* the
22
40
  * pod's filesystem.
23
41
  */
24
- import type { StorageDefinition } from "../storage.js";
42
+ import { type StorageDefinition } from "../storage.js";
43
+ import type { AgentArchitecture } from "../types.js";
25
44
  export interface FrameworkStorageSelectionInput {
26
- /** `agent/storage.ts`, when the author wrote one. */
45
+ /** `agent/storage.ts`, when the author wrote one (v1 only: discovery rejects it on v2). */
27
46
  readonly authored: StorageDefinition | undefined;
47
+ /** {@link AgentConfig.architecture}; omitted means v1. */
48
+ readonly architecture?: AgentArchitecture | undefined;
49
+ /** Environment override for tests; defaults to `process.env`. */
50
+ readonly env?: Record<string, string | undefined>;
28
51
  }
29
52
  /**
30
53
  * Pick the backend for framework session state.
31
54
  *
32
55
  * Returns `undefined` when there is no mirror, in which case the pod's local
33
- * disk is the only copy — the condition F0 exists to remove for hosted
34
- * deployments.
56
+ * disk is the only copy.
35
57
  */
36
58
  export declare function selectFrameworkStorageDefinition(input: FrameworkStorageSelectionInput): StorageDefinition | undefined;
37
59
  //# sourceMappingURL=framework-storage-selection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"framework-storage-selection.d.ts","sourceRoot":"","sources":["../../src/internal/framework-storage-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,8BAA8B;IAC7C,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAClD;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,8BAA8B,GACpC,iBAAiB,GAAG,SAAS,CAI/B"}
1
+ {"version":3,"file":"framework-storage-selection.d.ts","sourceRoot":"","sources":["../../src/internal/framework-storage-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAMH,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD,MAAM,WAAW,8BAA8B;IAC7C,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACjD,0DAA0D;IAC1D,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtD,iEAAiE;IACjE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACnD;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,8BAA8B,GACpC,iBAAiB,GAAG,SAAS,CAoD/B"}
@@ -2,34 +2,95 @@
2
2
  * Which backend framework session state is mirrored to.
3
3
  *
4
4
  * Framework state — session records, event chunks, the continuation index —
5
- * is how a session outlives the process that served it. Today that mirror
6
- * exists only when the agent author wrote `agent/storage.ts`, which makes
7
- * platform durability an agent-level decision: of the first-party agents,
8
- * some choose `cursorHostedStorage()` and some choose `fileKv()` (pod-local
9
- * disk, lost on pod replacement), and one selects between them at runtime by
10
- * reading the deployment-id environment variable itself.
5
+ * is how a session outlives the process that served it. On architecture v1
6
+ * that mirror exists only when the agent author wrote `agent/storage.ts`,
7
+ * which makes platform durability an agent-level decision: of the
8
+ * first-party agents, some choose `cursorHostedStorage()` and some choose
9
+ * `fileKv()` (pod-local disk, lost on pod replacement), and one selects
10
+ * between them at runtime by reading the deployment-id environment variable
11
+ * itself.
11
12
  *
12
- * That selection is a hosting-mode question, not an authoring question, and
13
- * this module is where it will move. It deliberately reproduces today's
14
- * behavior exactly for now authored definition or nothing so the change
15
- * that makes framework durability automatic is a change to
16
- * {@link selectFrameworkStorageDefinition} alone, reviewable on its own and
17
- * revertable without touching the engine.
13
+ * That selection is a hosting-mode question, not an authoring question.
14
+ * Architecture v2 moves it here: `agent/storage.ts` is rejected at
15
+ * discovery (error diagnostic, so serve and deploy fail early), and the
16
+ * platform picks the default
17
+ *
18
+ * - **Cursor-managed hosting** (the deployment-generation environment
19
+ * variable is set, same signal that registers `GET /v1/manifest`):
20
+ * the Cursor-hosted backend. When the deployment carries a
21
+ * **framework-level file store**
22
+ * (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`), session records, event
23
+ * transcripts, and the continuation index live there — file-shaped state
24
+ * on file storage, apart from the author-facing user store — while
25
+ * `host.kv`, eval runs, A/B samples, and conditional writes stay on the
26
+ * control-plane KV proxy (see framework-file-storage.ts). Without one
27
+ * (a deploy predating framework-store provisioning), everything goes to
28
+ * the KV proxy as before. The API key resolves through the full
29
+ * credential chain on every call because hosted freeze snapshots listen
30
+ * unsigned and the binder drops the key file after restore.
31
+ * - **Self-hosted**: no mirror. `--state-root` is the durable copy, which
32
+ * is correct when the operator owns the disk.
33
+ *
34
+ * v1 keeps the authored definition (or nothing) so existing deployments are
35
+ * untouched while they run.
18
36
  *
19
37
  * Local disk is not part of this decision. `<stateRoot>/sessions/<id>/`
20
38
  * already holds `session.json` and `events.ndjson` unconditionally, through
21
39
  * the session store; what this selects is the durable mirror *beyond* the
22
40
  * pod's filesystem.
23
41
  */
42
+ import { cursorFrameworkStoreSourceId, cursorHostedFiles, } from "../files-backends/cursor-hosted.js";
43
+ import { defineStorage } from "../storage.js";
44
+ import { cursorHostedStorage } from "../storage-backends/cursor-hosted.js";
45
+ import { resolveApiKeySync } from "./cursor/credentials.js";
46
+ import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
47
+ import { composeFrameworkStorage, fileSinkStorageCore, frameworkGuardedCas, } from "./framework-file-storage.js";
24
48
  /**
25
49
  * Pick the backend for framework session state.
26
50
  *
27
51
  * Returns `undefined` when there is no mirror, in which case the pod's local
28
- * disk is the only copy — the condition F0 exists to remove for hosted
29
- * deployments.
52
+ * disk is the only copy.
30
53
  */
31
54
  export function selectFrameworkStorageDefinition(input) {
32
- // Today: the author decides, or there is no mirror. Hosting-mode selection
33
- // replaces this body; every caller already routes through here.
34
- return input.authored;
55
+ var _a;
56
+ if (input.architecture !== "v2") {
57
+ // v1: the author decides, or there is no mirror.
58
+ return input.authored;
59
+ }
60
+ if (input.authored !== undefined) {
61
+ // Discovery rejects agent/storage.ts on v2 before an engine is built;
62
+ // an authored definition reaching this point is a wiring bug. Raise
63
+ // rather than silently discard what the author believes is configured.
64
+ throw new Error('defineStorage (agent/storage.ts) is not supported on architecture "v2": storage is platform-selected. Delete the file.');
65
+ }
66
+ const env = (_a = input.env) !== null && _a !== void 0 ? _a : process.env;
67
+ if (env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined) {
68
+ // Self-hosted v2: the state root is the durable copy.
69
+ return undefined;
70
+ }
71
+ // Hosted v2 pods wake per delivery: bulk-restoring up to the default
72
+ // 1000 sessions on every boot is waste (and against the file-store
73
+ // backend it is per-key HTTP round trips before the listener even
74
+ // comes up). Follow-ups restore lazily by continuation or session id;
75
+ // GET /v1/sessions lists from the sink either way.
76
+ const policy = { restore: "off" };
77
+ // Full chain (env → key file → stored login): frozen engines listen
78
+ // unsigned and bind CURSOR_API_KEY_FILE at task time, after this
79
+ // definition is constructed.
80
+ const resolveApiKey = () => { var _a; return (_a = resolveApiKeySync()) === null || _a === void 0 ? void 0 : _a.apiKey; };
81
+ const kv = cursorHostedStorage({ resolveApiKey });
82
+ const frameworkStoreId = cursorFrameworkStoreSourceId(env);
83
+ if (frameworkStoreId === undefined) {
84
+ return defineStorage(Object.assign({ name: "cursor-hosted", policy }, kv));
85
+ }
86
+ // Framework session state on the framework-level file store; author kv,
87
+ // evals, and A/B tables stay on the KV proxy (spread from `kv`, which
88
+ // also carries the cursor-hosted marker for GET /v1/sessions).
89
+ return defineStorage(Object.assign(Object.assign(Object.assign({ name: "cursor-hosted (framework files)", policy }, kv), composeFrameworkStorage({
90
+ kv,
91
+ files: fileSinkStorageCore(cursorHostedFiles({ storeSourceId: frameworkStoreId, resolveApiKey })),
92
+ })), {
93
+ // CAS stays on the KV proxy but must refuse framework-file keys, or a
94
+ // future coordination path would split-brain against the plain core.
95
+ cas: frameworkGuardedCas(kv.cas) }));
35
96
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A `send()` captured outside the delivery (typically at channel `onStart`,
3
+ * which binds directly to the engine) reached the engine during a hosted
4
+ * admission window. Running it would start a local July session on a
5
+ * sessionless pod — invisible to the control plane, destroyed with the pod —
6
+ * so it fails loudly instead. This is a deterministic authored bug and is
7
+ * surfaced as a non-retryable 422 by the admission route.
8
+ */
9
+ export declare class HostedAdmissionLocalSendError extends Error {
10
+ constructor();
11
+ }
12
+ /**
13
+ * Run `work` inside the hosted admission window. The context follows the
14
+ * async graph, including `waitUntil` task bodies scheduled during dispatch,
15
+ * so the engine can refuse local sends that bypass the capture stub.
16
+ */
17
+ export declare function runDuringHostedAdmission<T>(work: () => T): T;
18
+ /** True while executing inside a hosted admission window. */
19
+ export declare function isDuringHostedAdmission(): boolean;
20
+ //# sourceMappingURL=hosted-admission-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-admission-context.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-admission-context.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,cAQC;CACF;AAID;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5D;AAED,6DAA6D;AAC7D,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD"}
@@ -0,0 +1,31 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ /**
3
+ * A `send()` captured outside the delivery (typically at channel `onStart`,
4
+ * which binds directly to the engine) reached the engine during a hosted
5
+ * admission window. Running it would start a local July session on a
6
+ * sessionless pod — invisible to the control plane, destroyed with the pod —
7
+ * so it fails loudly instead. This is a deterministic authored bug and is
8
+ * surfaced as a non-retryable 422 by the admission route.
9
+ */
10
+ export class HostedAdmissionLocalSendError extends Error {
11
+ constructor() {
12
+ super("send() reached the local engine during hosted admission. A send " +
13
+ "captured at channel startup (onStart) bypasses hosted capture and " +
14
+ "would run an invisible local session on a sessionless pod. Use the " +
15
+ "per-delivery send passed to the task callback " +
16
+ "(task: (args) => args.send(…)) instead.");
17
+ }
18
+ }
19
+ const admissionWindow = new AsyncLocalStorage();
20
+ /**
21
+ * Run `work` inside the hosted admission window. The context follows the
22
+ * async graph, including `waitUntil` task bodies scheduled during dispatch,
23
+ * so the engine can refuse local sends that bypass the capture stub.
24
+ */
25
+ export function runDuringHostedAdmission(work) {
26
+ return admissionWindow.run(true, work);
27
+ }
28
+ /** True while executing inside a hosted admission window. */
29
+ export function isDuringHostedAdmission() {
30
+ return admissionWindow.getStore() === true;
31
+ }
@@ -2,6 +2,10 @@ export declare const HOSTED_DELIVERY_PROTOCOL_VERSION = 2;
2
2
  export declare const HOSTED_DELIVERY_HEADER = "x-agent-sdk-hosted-delivery";
3
3
  export declare const HOSTED_ADMISSION_PATH = "/v1/internal/hosted-admission";
4
4
  export declare const HOSTED_EXECUTION_PATH = "/v1/internal/hosted-execution";
5
+ export type HostedAdmissionManagedAutomation = {
6
+ automationUuid: string;
7
+ mcpServerNames: string[];
8
+ };
5
9
  export type HostedAdmission = {
6
10
  v: 2;
7
11
  channelId: string;
@@ -11,6 +15,7 @@ export type HostedAdmission = {
11
15
  sessionMode: "event" | "continuation";
12
16
  mailboxContinuationKey: string;
13
17
  payload: unknown;
18
+ managedAutomation?: HostedAdmissionManagedAutomation;
14
19
  };
15
20
  export type HostedAdmissionOutcome = {
16
21
  ok: true;
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-delivery-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-delivery-protocol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AACrE,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AAErE,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,EAAE,CAAC,CAAC;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,GAAG,cAAc,CAAC;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,EAAE,CAAC,CAAC;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,IAAI,CAAC;IACT,CAAC,EAAE,CAAC,CAAC;IACL,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAkBF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,eAAe,GAAG,SAAS,CAsB7B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,eAAe,GAAG,SAAS,CAe7B;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,sBAAsB,GAAG,SAAS,CAkBpC"}
1
+ {"version":3,"file":"hosted-delivery-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-delivery-protocol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AACrE,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AAErE,MAAM,MAAM,gCAAgC,GAAG;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,EAAE,CAAC,CAAC;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,GAAG,cAAc,CAAC;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,gCAAgC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,EAAE,CAAC,CAAC;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,IAAI,CAAC;IACT,CAAC,EAAE,CAAC,CAAC;IACL,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAsDF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,eAAe,GAAG,SAAS,CAuB7B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,eAAe,GAAG,SAAS,CAe7B;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,sBAAsB,GAAG,SAAS,CAkBpC"}
@@ -11,11 +11,42 @@ const DELIVERY_KEYS = new Set([
11
11
  "sessionMode",
12
12
  "mailboxContinuationKey",
13
13
  "payload",
14
+ "managedAutomation",
14
15
  ]);
16
+ const MANAGED_AUTOMATION_KEYS = new Set(["automationUuid", "mcpServerNames"]);
17
+ /** More names than any real automation configures is a malformed envelope. */
18
+ const MANAGED_AUTOMATION_MAX_SERVERS = 64;
15
19
  const EXECUTION_KEYS = new Set(["v", "admissionToken", "sessionPublicId"]);
16
20
  function boundedString(value, max) {
17
21
  return typeof value === "string" && value.length > 0 && value.length <= max;
18
22
  }
23
+ /**
24
+ * Parse the optional managed-automation slice. Absent → valid (undefined);
25
+ * present-but-malformed → invalid (the whole admission fails closed, the
26
+ * strict posture the rest of the envelope already takes).
27
+ */
28
+ function parseManagedAutomation(value) {
29
+ if (value === undefined) {
30
+ return {};
31
+ }
32
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
33
+ return undefined;
34
+ }
35
+ const body = value;
36
+ if (Object.keys(body).some((key) => !MANAGED_AUTOMATION_KEYS.has(key)) ||
37
+ !boundedString(body.automationUuid, 128) ||
38
+ !Array.isArray(body.mcpServerNames) ||
39
+ body.mcpServerNames.length > MANAGED_AUTOMATION_MAX_SERVERS ||
40
+ !body.mcpServerNames.every((name) => boundedString(name, 256))) {
41
+ return undefined;
42
+ }
43
+ return {
44
+ managedAutomation: {
45
+ automationUuid: body.automationUuid,
46
+ mcpServerNames: body.mcpServerNames,
47
+ },
48
+ };
49
+ }
19
50
  export function parseHostedAdmission(value) {
20
51
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
21
52
  return undefined;
@@ -29,7 +60,8 @@ export function parseHostedAdmission(value) {
29
60
  !boundedString(body.eventType, 128) ||
30
61
  !boundedString(body.deliveryId, 256) ||
31
62
  (body.sessionMode !== "event" && body.sessionMode !== "continuation") ||
32
- !boundedString(body.mailboxContinuationKey, 512)) {
63
+ !boundedString(body.mailboxContinuationKey, 512) ||
64
+ parseManagedAutomation(body.managedAutomation) === undefined) {
33
65
  return undefined;
34
66
  }
35
67
  const prefix = body.sessionMode === "event" ? "evt:" : "cont:";
@@ -18,8 +18,10 @@ type AdmissionDispatch = {
18
18
  };
19
19
  /**
20
20
  * Run authored admission without creating a framework session. V1 GitHub
21
- * `task` callbacks execute as sessionless work; `send` is captured and
22
- * resumed only after the control plane allocates `ses_…`.
21
+ * `task` callbacks execute as sessionless work; the first `send` is captured
22
+ * and executed only after the control plane allocates `ses_…`. Capturing
23
+ * does not terminate the caller — `send` returns an inert deferred handle so
24
+ * a task body runs to completion before the admission response is computed.
23
25
  */
24
26
  export declare function dispatchHostedAdmission(input: DispatchInput): Promise<AdmissionDispatch>;
25
27
  export declare function registerHostedDeliveryRoute(input: {
@@ -30,6 +32,13 @@ export declare function registerHostedDeliveryRoute(input: {
30
32
  definition: object;
31
33
  }>;
32
34
  buildHandlerArgs(channelId: string, sessionPublicId?: string): ChannelHandlerArgs;
35
+ /**
36
+ * Await the session's durable mirror (dispatch chain + storage queue)
37
+ * before the execution reply: the control plane may park the pod the
38
+ * moment the reply lands, and a shed session-record flush would strand
39
+ * the conversation on the next wake.
40
+ */
41
+ drainSessionDurability?(sessionId: string): Promise<void>;
33
42
  }): void;
34
43
  export {};
35
44
  //# sourceMappingURL=hosted-delivery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-delivery.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-delivery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,eAAe,EAGrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAgBF;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,iBAAiB,CAAC,CA2G5B;AAeD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,kBAAkB,CAAC;CACvB,GAAG,IAAI,CAqKP"}
1
+ {"version":3,"file":"hosted-delivery.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-delivery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AASrB,OAAO,EAKL,KAAK,eAAe,EAGrB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AA6DF;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAa5B;AA2GD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,kBAAkB,CAAC;IACtB;;;;;OAKG;IACH,sBAAsB,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D,GAAG,IAAI,CAyKP"}