@cursor/july 0.1.96 → 0.1.99

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 (381) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +3 -2
  3. package/dist/bin/agent-serve.js +13 -3
  4. package/dist/channels/github/github-channel.d.ts.map +1 -1
  5. package/dist/channels/github/github-channel.js +16 -0
  6. package/dist/channels/origin/api.d.ts +15 -4
  7. package/dist/channels/origin/api.d.ts.map +1 -1
  8. package/dist/channels/origin/api.js +19 -3
  9. package/dist/channels/origin/binding.d.ts +11 -0
  10. package/dist/channels/origin/binding.d.ts.map +1 -1
  11. package/dist/channels/origin/binding.js +41 -25
  12. package/dist/channels/origin/index.d.ts +1 -0
  13. package/dist/channels/origin/index.d.ts.map +1 -1
  14. package/dist/channels/origin/index.js +1 -0
  15. package/dist/channels/origin/origin-channel.d.ts +2 -0
  16. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  17. package/dist/channels/origin/origin-channel.js +40 -4
  18. package/dist/channels/origin/reactions.d.ts +56 -0
  19. package/dist/channels/origin/reactions.d.ts.map +1 -0
  20. package/dist/channels/origin/reactions.js +67 -0
  21. package/dist/channels/origin/types.d.ts +11 -0
  22. package/dist/channels/origin/types.d.ts.map +1 -1
  23. package/dist/channels/slack/approvals.d.ts +16 -0
  24. package/dist/channels/slack/approvals.d.ts.map +1 -1
  25. package/dist/channels/slack/approvals.js +86 -0
  26. package/dist/channels/slack/cli-project.d.ts +19 -0
  27. package/dist/channels/slack/cli-project.d.ts.map +1 -0
  28. package/dist/channels/slack/cli-project.js +234 -0
  29. package/dist/channels/slack/defaults.d.ts.map +1 -1
  30. package/dist/channels/slack/defaults.js +142 -63
  31. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  32. package/dist/channels/slack/dispatch.js +1 -1
  33. package/dist/channels/slack/init.d.ts +3 -2
  34. package/dist/channels/slack/init.d.ts.map +1 -1
  35. package/dist/channels/slack/init.js +5 -5
  36. package/dist/channels/slack/interactive.d.ts +2 -1
  37. package/dist/channels/slack/interactive.d.ts.map +1 -1
  38. package/dist/channels/slack/interactive.js +15 -4
  39. package/dist/channels/slack/live-delivery.d.ts +1 -1
  40. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  41. package/dist/channels/slack/live-delivery.js +4 -2
  42. package/dist/channels/slack/manifest.d.ts +1 -1
  43. package/dist/channels/slack/manifest.js +1 -1
  44. package/dist/channels/slack/progress-delivery.d.ts +28 -0
  45. package/dist/channels/slack/progress-delivery.d.ts.map +1 -0
  46. package/dist/channels/slack/progress-delivery.js +115 -0
  47. package/dist/channels/slack/setup.d.ts +1 -1
  48. package/dist/channels/slack/setup.d.ts.map +1 -1
  49. package/dist/channels/slack/setup.js +10 -6
  50. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  51. package/dist/channels/slack/slack-channel.js +1 -0
  52. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
  53. package/dist/channels/slack/tool-approval-events.js +91 -1
  54. package/dist/channels/slack/types.d.ts +9 -1
  55. package/dist/channels/slack/types.d.ts.map +1 -1
  56. package/dist/docs/404.html +2 -2
  57. package/dist/docs/ab.html +4 -4
  58. package/dist/docs/assets/{app.jXleCmOc.js → app.BplEAZ3S.js} +1 -1
  59. package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +1 -0
  60. package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.CHXyv4wP.js} +1 -1
  61. package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.BTcsZmjQ.js} +2 -2
  62. package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
  63. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
  64. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
  65. package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
  66. package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
  67. package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
  68. package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
  69. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.DfoeyvL0.js} +9 -6
  70. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
  71. package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
  72. package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.BEJx9XVj.js} +2 -2
  73. package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
  74. package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.CvAHsdSp.js} +10 -2
  75. package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
  76. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
  77. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
  78. package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
  79. package/dist/docs/building-with-agents.html +4 -4
  80. package/dist/docs/concepts.html +4 -4
  81. package/dist/docs/deployment.html +7 -7
  82. package/dist/docs/deployment.md +5 -4
  83. package/dist/docs/design/runtime-abstraction.md +1757 -0
  84. package/dist/docs/evals.html +4 -4
  85. package/dist/docs/guides/agent-to-agent.html +4 -4
  86. package/dist/docs/guides/cloud-runtime.html +4 -4
  87. package/dist/docs/guides/convert-automation.html +4 -4
  88. package/dist/docs/guides/github.html +4 -4
  89. package/dist/docs/guides/human-in-the-loop.html +4 -4
  90. package/dist/docs/guides/mcp-oauth.html +8 -8
  91. package/dist/docs/guides/mcp-oauth.md +26 -8
  92. package/dist/docs/guides/opentelemetry.html +4 -4
  93. package/dist/docs/guides/slack.html +17 -33
  94. package/dist/docs/guides/slack.md +92 -201
  95. package/dist/docs/guides/webhooks.html +4 -4
  96. package/dist/docs/hashmap.json +1 -1
  97. package/dist/docs/hillclimbing.html +4 -4
  98. package/dist/docs/index.html +6 -6
  99. package/dist/docs/index.md +5 -3
  100. package/dist/docs/llms-full.txt +2065 -637
  101. package/dist/docs/llms.txt +3 -2
  102. package/dist/docs/quickstart.html +4 -4
  103. package/dist/docs/reference/agent-config.html +6 -6
  104. package/dist/docs/reference/agent-config.md +2 -2
  105. package/dist/docs/reference/artifacts.html +4 -4
  106. package/dist/docs/reference/channels.html +4 -4
  107. package/dist/docs/reference/cli.html +13 -10
  108. package/dist/docs/reference/cli.md +32 -16
  109. package/dist/docs/reference/connections.html +9 -8
  110. package/dist/docs/reference/connections.md +6 -3
  111. package/dist/docs/reference/hooks.html +4 -4
  112. package/dist/docs/reference/http-api.html +7 -7
  113. package/dist/docs/reference/http-api.md +3 -1
  114. package/dist/docs/reference/instructions.html +4 -4
  115. package/dist/docs/reference/playground.html +4 -4
  116. package/dist/docs/reference/project-layout.html +4 -4
  117. package/dist/docs/reference/prompt.html +4 -4
  118. package/dist/docs/reference/schedules.html +4 -4
  119. package/dist/docs/reference/sessions.html +5 -5
  120. package/dist/docs/reference/sessions.md +4 -2
  121. package/dist/docs/reference/skills.html +4 -4
  122. package/dist/docs/reference/subagents.html +4 -4
  123. package/dist/docs/reference/tools.html +15 -7
  124. package/dist/docs/reference/tools.md +34 -2
  125. package/dist/docs/scaffolding-agents.html +4 -4
  126. package/dist/docs/storage.html +4 -4
  127. package/dist/docs/templates/agentic-owners.html +4 -4
  128. package/dist/docs/templates/agents-md.html +28 -0
  129. package/dist/docs/templates/agents-md.md +105 -0
  130. package/dist/docs/templates/code-wiki.html +5 -5
  131. package/dist/docs/templates/demo.html +4 -4
  132. package/dist/docs/templates/pr-autofixer.html +4 -4
  133. package/dist/docs/templates/security-help.html +4 -4
  134. package/dist/docs/templates/security-reviewer.html +5 -5
  135. package/dist/docs/templates/triage.html +4 -4
  136. package/dist/docs/troubleshooting.html +5 -5
  137. package/dist/docs/troubleshooting.md +2 -2
  138. package/dist/evals/run-facts.d.ts.map +1 -1
  139. package/dist/evals/run-facts.js +27 -0
  140. package/dist/files-backends/cursor-hosted.d.ts +3 -2
  141. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  142. package/dist/files-backends/cursor-hosted.js +3 -2
  143. package/dist/index.d.ts +1 -0
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +1 -0
  146. package/dist/internal/advertise-tools.d.ts.map +1 -1
  147. package/dist/internal/advertise-tools.js +15 -9
  148. package/dist/internal/approval-gate.d.ts +12 -13
  149. package/dist/internal/approval-gate.d.ts.map +1 -1
  150. package/dist/internal/approval-gate.js +16 -21
  151. package/dist/internal/as-of.d.ts +19 -0
  152. package/dist/internal/as-of.d.ts.map +1 -0
  153. package/dist/internal/as-of.js +82 -0
  154. package/dist/internal/chat-client.js +10 -0
  155. package/dist/internal/cli-deploy.d.ts +6 -0
  156. package/dist/internal/cli-deploy.d.ts.map +1 -1
  157. package/dist/internal/cli-deploy.js +149 -21
  158. package/dist/internal/cli-mcp-oauth.js +8 -18
  159. package/dist/internal/cli-slack-manual.d.ts +24 -2
  160. package/dist/internal/cli-slack-manual.d.ts.map +1 -1
  161. package/dist/internal/cli-slack-manual.js +251 -20
  162. package/dist/internal/cli-slack.d.ts +9 -2
  163. package/dist/internal/cli-slack.d.ts.map +1 -1
  164. package/dist/internal/cli-slack.js +29 -82
  165. package/dist/internal/cursor/account-mcp.d.ts +1 -0
  166. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  167. package/dist/internal/cursor/account-mcp.js +17 -0
  168. package/dist/internal/cursor-agent-template.d.ts +1 -1
  169. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  170. package/dist/internal/cursor-agent-template.js +1 -0
  171. package/dist/internal/cursor-event-relay.d.ts.map +1 -1
  172. package/dist/internal/cursor-event-relay.js +5 -6
  173. package/dist/internal/deploy-client.d.ts +17 -0
  174. package/dist/internal/deploy-client.d.ts.map +1 -1
  175. package/dist/internal/deploy-client.js +31 -10
  176. package/dist/internal/env-file.d.ts +19 -0
  177. package/dist/internal/env-file.d.ts.map +1 -0
  178. package/dist/internal/env-file.js +90 -0
  179. package/dist/internal/framework-file-storage.d.ts +11 -17
  180. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  181. package/dist/internal/framework-file-storage.js +17 -40
  182. package/dist/internal/framework-storage-selection.d.ts +13 -11
  183. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  184. package/dist/internal/framework-storage-selection.js +37 -26
  185. package/dist/internal/hosted-admission-adapter.d.ts +28 -0
  186. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -0
  187. package/dist/internal/hosted-admission-adapter.js +7 -0
  188. package/dist/internal/hosted-delivery-protocol.d.ts +13 -1
  189. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  190. package/dist/internal/hosted-delivery-protocol.js +8 -1
  191. package/dist/internal/hosted-delivery.d.ts +21 -1
  192. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  193. package/dist/internal/hosted-delivery.js +101 -34
  194. package/dist/internal/hosted-execution-diag.d.ts +59 -0
  195. package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
  196. package/dist/internal/hosted-execution-diag.js +187 -0
  197. package/dist/internal/http-channel.d.ts.map +1 -1
  198. package/dist/internal/http-channel.js +85 -2
  199. package/dist/internal/init-project.d.ts.map +1 -1
  200. package/dist/internal/init-project.js +2 -0
  201. package/dist/internal/logs-client.d.ts +5 -0
  202. package/dist/internal/logs-client.d.ts.map +1 -1
  203. package/dist/internal/logs-client.js +5 -0
  204. package/dist/internal/mcp-endpoint.js +2 -3
  205. package/dist/internal/mcp-host.d.ts +10 -0
  206. package/dist/internal/mcp-host.d.ts.map +1 -1
  207. package/dist/internal/mcp-host.js +57 -8
  208. package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
  209. package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
  210. package/dist/internal/mcp-oauth-on-demand.js +287 -0
  211. package/dist/internal/mcp-oauth-persist.d.ts +42 -0
  212. package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
  213. package/dist/internal/mcp-oauth-persist.js +92 -0
  214. package/dist/internal/mcp-oauth.d.ts +1 -0
  215. package/dist/internal/mcp-oauth.d.ts.map +1 -1
  216. package/dist/internal/mcp-oauth.js +10 -2
  217. package/dist/internal/null-kv-storage.d.ts +48 -0
  218. package/dist/internal/null-kv-storage.d.ts.map +1 -0
  219. package/dist/internal/null-kv-storage.js +58 -0
  220. package/dist/internal/otel/collector.d.ts.map +1 -1
  221. package/dist/internal/otel/collector.js +22 -9
  222. package/dist/internal/server.d.ts +6 -0
  223. package/dist/internal/server.d.ts.map +1 -1
  224. package/dist/internal/server.js +123 -33
  225. package/dist/internal/session-engine.d.ts +88 -3
  226. package/dist/internal/session-engine.d.ts.map +1 -1
  227. package/dist/internal/session-engine.js +538 -46
  228. package/dist/internal/session-run-log.d.ts +120 -0
  229. package/dist/internal/session-run-log.d.ts.map +1 -0
  230. package/dist/internal/session-run-log.js +359 -0
  231. package/dist/internal/sessions-client.d.ts +9 -7
  232. package/dist/internal/sessions-client.d.ts.map +1 -1
  233. package/dist/internal/sessions-client.js +3 -1
  234. package/dist/internal/storage-coordinator.d.ts +13 -0
  235. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  236. package/dist/internal/storage-coordinator.js +37 -6
  237. package/dist/internal/storage-roles.d.ts +5 -0
  238. package/dist/internal/storage-roles.d.ts.map +1 -1
  239. package/dist/internal/stream-progress.d.ts.map +1 -1
  240. package/dist/internal/stream-progress.js +10 -0
  241. package/dist/internal/tool-policy.d.ts +29 -9
  242. package/dist/internal/tool-policy.d.ts.map +1 -1
  243. package/dist/internal/tool-policy.js +24 -0
  244. package/dist/internal/trajectory.d.ts.map +1 -1
  245. package/dist/internal/trajectory.js +10 -0
  246. package/dist/internal/turn-outbox.d.ts +24 -0
  247. package/dist/internal/turn-outbox.d.ts.map +1 -0
  248. package/dist/internal/turn-outbox.js +80 -0
  249. package/dist/playground/assets/index-D7rGZNjy.css +1 -0
  250. package/dist/playground/assets/index-jzNbJENa.js +69 -0
  251. package/dist/playground/index.html +2 -2
  252. package/dist/storage-backends/cursor-hosted.d.ts +1 -1
  253. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  254. package/dist/storage-backends/cursor-hosted.js +12 -0
  255. package/dist/storage-protocol.d.ts +8 -0
  256. package/dist/storage-protocol.d.ts.map +1 -1
  257. package/dist/storage-protocol.js +8 -0
  258. package/dist/storage.d.ts +8 -0
  259. package/dist/storage.d.ts.map +1 -1
  260. package/dist/tools.d.ts +12 -2
  261. package/dist/tools.d.ts.map +1 -1
  262. package/dist/types.d.ts +88 -7
  263. package/dist/types.d.ts.map +1 -1
  264. package/docs/README.md +5 -3
  265. package/docs/deployment.md +5 -4
  266. package/docs/design/runtime-abstraction.md +1757 -0
  267. package/docs/guides/mcp-oauth.md +26 -8
  268. package/docs/guides/slack.md +93 -202
  269. package/docs/reference/agent-config.md +2 -2
  270. package/docs/reference/cli.md +32 -16
  271. package/docs/reference/connections.md +6 -3
  272. package/docs/reference/http-api.md +3 -1
  273. package/docs/reference/sessions.md +4 -2
  274. package/docs/reference/tools.md +34 -2
  275. package/docs/templates/agents-md.md +110 -0
  276. package/docs/troubleshooting.md +2 -2
  277. package/package.json +1 -1
  278. package/skills/create-agent/SKILL.md +2 -1
  279. package/skills/mcp-auth/SKILL.md +6 -3
  280. package/skills/setup-slack/SKILL.md +23 -13
  281. package/src/bin/agent-serve.ts +12 -1
  282. package/src/channels/github/github-channel.ts +17 -0
  283. package/src/channels/origin/api.ts +24 -5
  284. package/src/channels/origin/binding.ts +55 -26
  285. package/src/channels/origin/index.ts +1 -0
  286. package/src/channels/origin/origin-channel.ts +78 -10
  287. package/src/channels/origin/reactions.ts +82 -0
  288. package/src/channels/origin/types.ts +11 -0
  289. package/src/channels/slack/approvals.ts +105 -0
  290. package/src/channels/slack/cli-project.ts +267 -0
  291. package/src/channels/slack/defaults.ts +165 -74
  292. package/src/channels/slack/dispatch.ts +2 -0
  293. package/src/channels/slack/init.ts +10 -5
  294. package/src/channels/slack/interactive.ts +35 -9
  295. package/src/channels/slack/live-delivery.ts +5 -3
  296. package/src/channels/slack/manifest.ts +1 -1
  297. package/src/channels/slack/progress-delivery.ts +133 -0
  298. package/src/channels/slack/setup.ts +10 -6
  299. package/src/channels/slack/slack-channel.ts +1 -0
  300. package/src/channels/slack/tool-approval-events.ts +93 -0
  301. package/src/channels/slack/types.ts +9 -1
  302. package/src/evals/run-facts.ts +32 -0
  303. package/src/files-backends/cursor-hosted.ts +3 -2
  304. package/src/index.ts +4 -0
  305. package/src/internal/advertise-tools.ts +31 -10
  306. package/src/internal/approval-gate.ts +20 -29
  307. package/src/internal/as-of.ts +107 -0
  308. package/src/internal/chat-client.ts +19 -0
  309. package/src/internal/cli-deploy.ts +203 -13
  310. package/src/internal/cli-mcp-oauth.ts +7 -21
  311. package/src/internal/cli-slack-manual.ts +350 -18
  312. package/src/internal/cli-slack.ts +40 -84
  313. package/src/internal/cursor/account-mcp.ts +21 -0
  314. package/src/internal/cursor-agent-template.ts +1 -0
  315. package/src/internal/cursor-event-relay.ts +5 -6
  316. package/src/internal/deploy-client.ts +43 -0
  317. package/src/internal/env-file.ts +84 -0
  318. package/src/internal/framework-file-storage.ts +18 -46
  319. package/src/internal/framework-storage-selection.ts +41 -25
  320. package/src/internal/hosted-admission-adapter.ts +42 -0
  321. package/src/internal/hosted-delivery-protocol.ts +14 -2
  322. package/src/internal/hosted-delivery.ts +169 -44
  323. package/src/internal/hosted-execution-diag.ts +252 -0
  324. package/src/internal/http-channel.ts +107 -0
  325. package/src/internal/init-project.ts +2 -0
  326. package/src/internal/logs-client.ts +5 -0
  327. package/src/internal/mcp-endpoint.ts +13 -4
  328. package/src/internal/mcp-host.ts +77 -11
  329. package/src/internal/mcp-oauth-on-demand.ts +352 -0
  330. package/src/internal/mcp-oauth-persist.ts +127 -0
  331. package/src/internal/mcp-oauth.ts +17 -1
  332. package/src/internal/null-kv-storage.ts +74 -0
  333. package/src/internal/otel/collector.ts +30 -0
  334. package/src/internal/server.ts +159 -11
  335. package/src/internal/session-engine.ts +691 -57
  336. package/src/internal/session-run-log.ts +584 -0
  337. package/src/internal/sessions-client.ts +17 -8
  338. package/src/internal/storage-coordinator.ts +49 -9
  339. package/src/internal/storage-roles.ts +7 -0
  340. package/src/internal/stream-progress.ts +19 -0
  341. package/src/internal/tool-policy.ts +49 -9
  342. package/src/internal/trajectory.ts +10 -0
  343. package/src/internal/turn-outbox.ts +85 -0
  344. package/src/storage-backends/cursor-hosted.ts +13 -1
  345. package/src/storage-protocol.ts +10 -0
  346. package/src/storage.ts +12 -0
  347. package/src/tools.ts +12 -2
  348. package/src/types.ts +93 -8
  349. package/templates/agents-md/README.md +39 -0
  350. package/templates/agents-md/agent/agent.ts +8 -0
  351. package/templates/agents-md/agent/channels/github.ts +10 -0
  352. package/templates/agents-md/agent/channels/queue.ts +28 -0
  353. package/templates/agents-md/agent/channels/slack.ts +9 -0
  354. package/templates/agents-md/agent/instructions.md +39 -0
  355. package/templates/agents-md/agent/lib/collect.ts +439 -0
  356. package/templates/agents-md/agent/lib/config.ts +8 -0
  357. package/templates/agents-md/agent/lib/paths.ts +51 -0
  358. package/templates/agents-md/agent/schedules/weekly.ts +17 -0
  359. package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
  360. package/templates/agents-md/evals/agents.eval.ts +135 -0
  361. package/templates/agents-md/evals/evals.config.ts +5 -0
  362. package/templates/agents-md/init.json +38 -0
  363. package/templates/agents-md/package.json +18 -0
  364. package/templates/agents-md/tsconfig.json +12 -0
  365. package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
  366. package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
  367. package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
  368. package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
  369. package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
  370. package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
  371. package/dist/docs/design/agsh.md +0 -406
  372. package/dist/playground/assets/index-B1DDvBeC.css +0 -1
  373. package/dist/playground/assets/index-Cx9CclK_.js +0 -88
  374. package/docs/design/agsh.md +0 -406
  375. /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
  376. /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
  377. /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
  378. /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
  379. /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
  380. /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
  381. /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
@@ -1,6 +1,8 @@
1
1
  import type { ChannelHandlerArgs, SendMessageOptions } from "../types.js";
2
2
  import { type HostedAdmission } from "./hosted-delivery-protocol.js";
3
+ import type { LogRingEntry } from "./log-ring.js";
3
4
  import type { Router } from "./router.js";
5
+ import { type SessionRunExecutionWrite } from "./session-run-log.js";
4
6
  type DispatchInput = {
5
7
  delivery: HostedAdmission;
6
8
  definition: object;
@@ -17,11 +19,14 @@ type AdmissionDispatch = {
17
19
  pendingSend?: PendingSend;
18
20
  };
19
21
  /**
20
- * Run authored admission without creating a framework session. V1 GitHub
22
+ * Run authored admission without creating a framework session. Authored
21
23
  * `task` callbacks execute as sessionless work; the first `send` is captured
22
24
  * and executed only after the control plane allocates `ses_…`. Capturing
23
25
  * does not terminate the caller — `send` returns an inert deferred handle so
24
26
  * a task body runs to completion before the admission response is computed.
27
+ *
28
+ * Dispatch is the adapter the mounted channel attached. Hosted delivery
29
+ * does not switch on `channelKind`.
25
30
  */
26
31
  export declare function dispatchHostedAdmission(input: DispatchInput): Promise<AdmissionDispatch>;
27
32
  export declare function registerHostedDeliveryRoute(input: {
@@ -39,6 +44,21 @@ export declare function registerHostedDeliveryRoute(input: {
39
44
  * the conversation on the next wake.
40
45
  */
41
46
  drainSessionDurability?(sessionId: string): Promise<void>;
47
+ /**
48
+ * Serve `--state-root` (not the per-slug SessionEngine dir). Hosted
49
+ * freeze is `/workspace/.agent-serve`; the Temporal host reads
50
+ * `hosted-execution.json` from that path after the POST returns.
51
+ */
52
+ stateRoot?: string;
53
+ /**
54
+ * Upsert this execution into the v2 session-level framework-store log.
55
+ * Called for the pre-turn `running` claim and every terminal outcome so
56
+ * a dead Node process still leaves a leftover. Soft-fail inside the
57
+ * store; this path still awaits so a parked pod cannot shed the write.
58
+ */
59
+ persistSessionRun?(write: SessionRunExecutionWrite): Promise<void>;
60
+ /** Snapshot of the process log ring at persist time. */
61
+ snapshotLogs?(): LogRingEntry[];
42
62
  }): void;
43
63
  export {};
44
64
  //# 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;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"}
1
+ {"version":3,"file":"hosted-delivery.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-delivery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAarB,OAAO,EAKL,KAAK,eAAe,EAGrB,MAAM,+BAA+B,CAAC;AAUvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,KAAK,wBAAwB,EAG9B,MAAM,sBAAsB,CAAC;AAE9B,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;;;;;;;;;GASG;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;IAC1D;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,wDAAwD;IACxD,YAAY,CAAC,IAAI,YAAY,EAAE,CAAC;CACjC,GAAG,IAAI,CAyQP"}
@@ -8,12 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { randomBytes } from "node:crypto";
11
- import { dispatchGitHubWebhook, getGitHubChannelOptions, getGitHubDispatchOutcome, withPropagatingGitHubBackgroundErrors, } from "../channels/github/github-channel.js";
12
11
  import { createDeferredChannelSession, DeferredChannelSessionError, } from "./deferred-channel-session.js";
12
+ import { getHostedAdmissionAdapter, } from "./hosted-admission-adapter.js";
13
13
  import { HostedAdmissionLocalSendError, runDuringHostedAdmission, } from "./hosted-admission-context.js";
14
14
  import { HOSTED_ADMISSION_PATH, HOSTED_DELIVERY_HEADER, HOSTED_DELIVERY_PROTOCOL_VERSION, HOSTED_EXECUTION_PATH, parseHostedAdmission, parseHostedExecution, } from "./hosted-delivery-protocol.js";
15
+ import { abortReasonFromTurnStatus, HOSTED_EXECUTION_DIAG_RUNNING_STATUS, hostedErrorStackSnippet, hostedExecutionDiagId, writeHostedExecutionDiag, } from "./hosted-execution-diag.js";
15
16
  import { recordHostedManagedAutomation } from "./hosted-managed-automation.js";
16
17
  import { errorResponse, readJsonObject } from "./http-channel.js";
18
+ import { serializeSessionRunError, snapshotSessionRunLogs, } from "./session-run-log.js";
17
19
  /**
18
20
  * A second `send()` in one delivery is a deterministic authored bug — the
19
21
  * wire protocol carries exactly one pending send per delivery — so it must
@@ -58,30 +60,35 @@ function nonRetryableRejection(error) {
58
60
  };
59
61
  }
60
62
  /**
61
- * Run authored admission without creating a framework session. V1 GitHub
63
+ * Run authored admission without creating a framework session. Authored
62
64
  * `task` callbacks execute as sessionless work; the first `send` is captured
63
65
  * and executed only after the control plane allocates `ses_…`. Capturing
64
66
  * does not terminate the caller — `send` returns an inert deferred handle so
65
67
  * a task body runs to completion before the admission response is computed.
68
+ *
69
+ * Dispatch is the adapter the mounted channel attached. Hosted delivery
70
+ * does not switch on `channelKind`.
66
71
  */
67
72
  export function dispatchHostedAdmission(input) {
68
73
  return __awaiter(this, void 0, void 0, function* () {
69
- const github = getGitHubChannelOptions(input.definition);
70
- if (github === undefined) {
74
+ const adapter = getHostedAdmissionAdapter(input.definition);
75
+ if (adapter === undefined || adapter.kind !== input.delivery.channelKind) {
71
76
  return {
72
77
  response: Response.json({ ok: false, error: "channel_kind_mismatch" }, { status: 422 }),
73
78
  };
74
79
  }
75
80
  // The admission window marker follows the async graph into task bodies so
76
81
  // the engine can refuse local sends that would bypass the capture stub.
77
- return runDuringHostedAdmission(() => runAdmission(input, github));
82
+ return runDuringHostedAdmission(() => runAdmission(input, adapter));
78
83
  });
79
84
  }
80
- function runAdmission(input, github) {
85
+ function runAdmission(input, adapter) {
81
86
  return __awaiter(this, void 0, void 0, function* () {
87
+ var _a;
88
+ var _b;
82
89
  const background = [];
83
90
  let captured;
84
- const args = withPropagatingGitHubBackgroundErrors(Object.assign(Object.assign({}, input.args), { send: (message_1, ...args_1) => __awaiter(this, [message_1, ...args_1], void 0, function* (message, options = {}) {
91
+ const capturingArgs = Object.assign(Object.assign({}, input.args), { send: (message_1, ...args_1) => __awaiter(this, [message_1, ...args_1], void 0, function* (message, options = {}) {
85
92
  if (captured !== undefined) {
86
93
  throw new HostedSendLimitExceeded();
87
94
  }
@@ -89,12 +96,12 @@ function runAdmission(input, github) {
89
96
  return createDeferredChannelSession();
90
97
  }), waitUntil: (promise) => {
91
98
  background.push(promise);
92
- } }));
99
+ } });
100
+ const args = (_b = (_a = adapter.prepareArgs) === null || _a === void 0 ? void 0 : _a.call(adapter, capturingArgs)) !== null && _b !== void 0 ? _b : capturingArgs;
93
101
  let dispatched;
94
102
  try {
95
- dispatched = yield dispatchGitHubWebhook({
96
- options: github,
97
- eventName: input.delivery.eventType,
103
+ dispatched = yield adapter.dispatch({
104
+ eventType: input.delivery.eventType,
98
105
  payload: input.delivery.payload,
99
106
  deliveryId: input.delivery.deliveryId,
100
107
  args,
@@ -139,7 +146,7 @@ function runAdmission(input, github) {
139
146
  },
140
147
  };
141
148
  }
142
- const outcome = getGitHubDispatchOutcome(dispatched);
149
+ const outcome = adapter.getOutcome(dispatched);
143
150
  if (outcome === undefined) {
144
151
  return {
145
152
  response: Response.json({ ok: false, error: "channel_outcome_missing" }, { status: 502 }),
@@ -248,33 +255,93 @@ export function registerHostedDeliveryRoute(input) {
248
255
  admitted.sessionPublicId = execution.sessionPublicId;
249
256
  (_a = admitted.execution) !== null && _a !== void 0 ? _a : (admitted.execution = (() => __awaiter(this, void 0, void 0, function* () {
250
257
  var _a;
251
- const args = input.buildHandlerArgs(admitted.send.channelId, execution.sessionPublicId);
252
- const session = yield args.send(admitted.send.message, Object.assign(Object.assign({}, admitted.send.options), { mailboxContinuation: {
253
- key: admitted.send.mailboxContinuationKey,
254
- } }));
255
- const outcome = yield session.waitForCompletion();
256
- // Failed turns drain too: their record/continuation updates must
257
- // survive the park just like a finished turn's.
258
- yield (_a = input.drainSessionDurability) === null || _a === void 0 ? void 0 : _a.call(input, session.id);
259
- if (outcome.status !== "finished") {
258
+ const startedAt = performance.now();
259
+ const executionId = hostedExecutionDiagId(execution.admissionToken);
260
+ const writeDiag = (fields) => __awaiter(this, void 0, void 0, function* () {
261
+ var _a;
262
+ var _b;
263
+ const durationMs = Math.max(0, Math.round(performance.now() - startedAt));
264
+ const message = fields.message === undefined
265
+ ? undefined
266
+ : boundedMessage(fields.message);
267
+ const stack = fields.error === undefined
268
+ ? undefined
269
+ : hostedErrorStackSnippet(fields.error);
270
+ if (input.stateRoot !== undefined) {
271
+ yield writeHostedExecutionDiag(input.stateRoot, Object.assign(Object.assign(Object.assign(Object.assign({ v: 1, executionId, writtenAt: new Date().toISOString(), sessionPublicId: execution.sessionPublicId, sessionId: fields.sessionId, turnStatus: fields.turnStatus, durationMs }, (message === undefined ? {} : { message })), (stack === undefined || stack.length === 0 ? {} : { stack })), (message !== undefined && /abort/i.test(message)
272
+ ? { signalAborted: true }
273
+ : {})), (fields.abortReason === undefined
274
+ ? {}
275
+ : { abortReason: fields.abortReason })));
276
+ }
277
+ if (input.persistSessionRun === undefined) {
278
+ return;
279
+ }
280
+ const error = fields.error === undefined
281
+ ? undefined
282
+ : serializeSessionRunError(fields.error);
283
+ try {
284
+ yield input.persistSessionRun(Object.assign(Object.assign(Object.assign(Object.assign({ executionId, writtenAt: new Date().toISOString(), sessionPublicId: execution.sessionPublicId, sessionId: fields.sessionId, turnStatus: fields.turnStatus, durationMs }, (fields.abortReason === undefined
285
+ ? {}
286
+ : { abortReason: fields.abortReason })), (message === undefined ? {} : { message })), (error === undefined ? {} : { error })), { logs: snapshotSessionRunLogs((_b = (_a = input.snapshotLogs) === null || _a === void 0 ? void 0 : _a.call(input)) !== null && _b !== void 0 ? _b : []) }));
287
+ }
288
+ catch (_c) {
289
+ // Soft-fail: a store outage must not change the HTTP reply.
290
+ }
291
+ });
292
+ // Claim the file before the turn runs. The host reads it after its
293
+ // own POST returns, which for a 9-minute timeout is while this turn
294
+ // is still going; without this marker that read would surface the
295
+ // PREVIOUS delivery's terminal record as if it were this one's.
296
+ yield writeDiag({
297
+ sessionId: "",
298
+ turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
299
+ });
300
+ try {
301
+ const args = input.buildHandlerArgs(admitted.send.channelId, execution.sessionPublicId);
302
+ const session = yield args.send(admitted.send.message, Object.assign(Object.assign({}, admitted.send.options), { mailboxContinuation: {
303
+ key: admitted.send.mailboxContinuationKey,
304
+ } }));
305
+ const outcome = yield session.waitForCompletion();
306
+ // Failed turns drain too: their record/continuation updates must
307
+ // survive the park just like a finished turn's.
308
+ yield (_a = input.drainSessionDurability) === null || _a === void 0 ? void 0 : _a.call(input, session.id);
309
+ yield writeDiag({
310
+ sessionId: session.id,
311
+ turnStatus: outcome.status,
312
+ message: outcome.errorMessage,
313
+ abortReason: abortReasonFromTurnStatus(outcome.status, outcome.errorMessage),
314
+ });
315
+ if (outcome.status !== "finished") {
316
+ return {
317
+ status: 503,
318
+ body: {
319
+ ok: false,
320
+ error: "turn_failed",
321
+ turnStatus: outcome.status,
322
+ message: outcome.errorMessage,
323
+ },
324
+ };
325
+ }
260
326
  return {
261
- status: 503,
327
+ status: 200,
262
328
  body: {
263
- ok: false,
264
- error: "turn_failed",
265
- turnStatus: outcome.status,
266
- message: outcome.errorMessage,
329
+ ok: true,
330
+ v: HOSTED_DELIVERY_PROTOCOL_VERSION,
331
+ outcome: "send",
267
332
  },
268
333
  };
269
334
  }
270
- return {
271
- status: 200,
272
- body: {
273
- ok: true,
274
- v: HOSTED_DELIVERY_PROTOCOL_VERSION,
275
- outcome: "send",
276
- },
277
- };
335
+ catch (error) {
336
+ yield writeDiag({
337
+ sessionId: "",
338
+ turnStatus: "error",
339
+ message: error instanceof Error ? error.message : String(error),
340
+ abortReason: "execute_throw",
341
+ error,
342
+ });
343
+ throw error;
344
+ }
278
345
  }))());
279
346
  const reply = yield admitted.execution;
280
347
  return finish(Response.json(reply.body, { status: reply.status }));
@@ -0,0 +1,59 @@
1
+ export declare const HOSTED_EXECUTION_DIAG_VERSION = 1;
2
+ /** Cap so a runaway message cannot fill the guest disk or the host log. */
3
+ export declare const HOSTED_EXECUTION_DIAG_MAX_BYTES = 4096;
4
+ /**
5
+ * Correlate the on-disk record with the execution that produced it. One pod
6
+ * serves many deliveries of a continuation session, and the file lives at a
7
+ * single fixed path, so without this the host can read a *previous*
8
+ * delivery's terminal record whenever July never reaches its own write —
9
+ * the 9-minute host POST timeout, a 409 on an expired admission token, or a
10
+ * replayed token that short-circuits on the memoized reply.
11
+ *
12
+ * Derived from the admission token (which both sides already hold) rather
13
+ * than carried on the wire. The digest is one-way, so the token itself never
14
+ * reaches the guest disk or the host logs.
15
+ */
16
+ export declare function hostedExecutionDiagId(admissionToken: string): string;
17
+ export type HostedExecutionDiagAbortReason = "signal_abort" | "runner_cancelled" | "runner_error" | "execute_throw";
18
+ /**
19
+ * Bounded guest-side record of one hosted-execution attempt. No prompt,
20
+ * tool content, or API key — the host copies known keys onto the Temporal
21
+ * activity span for Datadog.
22
+ */
23
+ export type HostedExecutionDiag = {
24
+ v: typeof HOSTED_EXECUTION_DIAG_VERSION;
25
+ /** {@link hostedExecutionDiagId} of the execution that wrote this record. */
26
+ executionId: string;
27
+ writtenAt: string;
28
+ sessionPublicId: string;
29
+ sessionId: string;
30
+ /** Terminal {@link TurnOutcome} status, or `running` before the turn ends. */
31
+ turnStatus: string;
32
+ durationMs: number;
33
+ message?: string;
34
+ /** First frames of a thrown Error; omitted on soft turn failures. */
35
+ stack?: string;
36
+ signalAborted?: boolean;
37
+ requestId?: string;
38
+ abortReason?: HostedExecutionDiagAbortReason;
39
+ };
40
+ /** Written before the turn starts so a stalled execution still has a record. */
41
+ export declare const HOSTED_EXECUTION_DIAG_RUNNING_STATUS = "running";
42
+ /** First line + frames; factory `last_error` is 1024 chars with a TAS prefix. */
43
+ export declare const HOSTED_ERROR_STACK_LINE_COUNT = 5;
44
+ export declare const HOSTED_ERROR_SNIPPET_MAX_CHARS = 700;
45
+ /**
46
+ * Bounded throw text for the hosted 500 body and the on-disk diag `stack`.
47
+ * Prefers `Error.stack` (message line + `at` frames) so `last_error` is not
48
+ * the generic "Internal server error." when the throw has a stack.
49
+ */
50
+ export declare function hostedErrorStackSnippet(error: unknown): string;
51
+ export declare function hostedExecutionDiagPath(stateRoot: string): string;
52
+ export declare function abortReasonFromTurnStatus(status: string, message: string | undefined): HostedExecutionDiagAbortReason | undefined;
53
+ export declare function parseHostedExecutionDiag(raw: string): HostedExecutionDiag | undefined;
54
+ /**
55
+ * Overwrite the per-execution diag file. Soft-fail: a write error must not
56
+ * change the hosted-execution HTTP reply.
57
+ */
58
+ export declare function writeHostedExecutionDiag(stateRoot: string, diag: HostedExecutionDiag): Promise<void>;
59
+ //# sourceMappingURL=hosted-execution-diag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-execution-diag.d.ts","sourceRoot":"","sources":["../../src/internal/hosted-execution-diag.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,2EAA2E;AAC3E,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,MAAM,MAAM,8BAA8B,GACtC,cAAc,GACd,kBAAkB,GAClB,cAAc,GACd,eAAe,CAAC;AAEpB;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,CAAC,EAAE,OAAO,6BAA6B,CAAC;IACxC,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,8BAA8B,CAAC;CAC9C,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,oCAAoC,YAAY,CAAC;AAmC9D,iFAAiF;AACjF,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAyB9D;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,8BAA8B,GAAG,SAAS,CAU5C;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,GACV,mBAAmB,GAAG,SAAS,CA2EjC;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -0,0 +1,187 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { createHash, randomBytes } from "node:crypto";
11
+ import { mkdir, rename, unlink, writeFile } from "node:fs/promises";
12
+ import { join } from "node:path";
13
+ import { HOSTED_EXECUTION_DIAG_FILENAME } from "./hosted-delivery-protocol.js";
14
+ export const HOSTED_EXECUTION_DIAG_VERSION = 1;
15
+ /** Cap so a runaway message cannot fill the guest disk or the host log. */
16
+ export const HOSTED_EXECUTION_DIAG_MAX_BYTES = 4096;
17
+ /**
18
+ * Correlate the on-disk record with the execution that produced it. One pod
19
+ * serves many deliveries of a continuation session, and the file lives at a
20
+ * single fixed path, so without this the host can read a *previous*
21
+ * delivery's terminal record whenever July never reaches its own write —
22
+ * the 9-minute host POST timeout, a 409 on an expired admission token, or a
23
+ * replayed token that short-circuits on the memoized reply.
24
+ *
25
+ * Derived from the admission token (which both sides already hold) rather
26
+ * than carried on the wire. The digest is one-way, so the token itself never
27
+ * reaches the guest disk or the host logs.
28
+ */
29
+ export function hostedExecutionDiagId(admissionToken) {
30
+ return createHash("sha256").update(admissionToken).digest("hex").slice(0, 16);
31
+ }
32
+ /** Written before the turn starts so a stalled execution still has a record. */
33
+ export const HOSTED_EXECUTION_DIAG_RUNNING_STATUS = "running";
34
+ const DIAG_KEYS = new Set([
35
+ "v",
36
+ "executionId",
37
+ "writtenAt",
38
+ "sessionPublicId",
39
+ "sessionId",
40
+ "turnStatus",
41
+ "durationMs",
42
+ "message",
43
+ "stack",
44
+ "signalAborted",
45
+ "requestId",
46
+ "abortReason",
47
+ ]);
48
+ const ABORT_REASONS = new Set([
49
+ "signal_abort",
50
+ "runner_cancelled",
51
+ "runner_error",
52
+ "execute_throw",
53
+ ]);
54
+ function boundedOptionalString(value, max) {
55
+ return typeof value === "string" && value.length > 0
56
+ ? value.length > max
57
+ ? `${value.slice(0, max)}…`
58
+ : value
59
+ : undefined;
60
+ }
61
+ /** First line + frames; factory `last_error` is 1024 chars with a TAS prefix. */
62
+ export const HOSTED_ERROR_STACK_LINE_COUNT = 5;
63
+ export const HOSTED_ERROR_SNIPPET_MAX_CHARS = 700;
64
+ /**
65
+ * Bounded throw text for the hosted 500 body and the on-disk diag `stack`.
66
+ * Prefers `Error.stack` (message line + `at` frames) so `last_error` is not
67
+ * the generic "Internal server error." when the throw has a stack.
68
+ */
69
+ export function hostedErrorStackSnippet(error) {
70
+ var _a;
71
+ if (error instanceof Error) {
72
+ const stack = (_a = error.stack) === null || _a === void 0 ? void 0 : _a.trim();
73
+ if (stack !== undefined && stack.length > 0) {
74
+ const lines = stack
75
+ .split("\n")
76
+ .map((line) => line.trimEnd())
77
+ .filter((line) => line.trim().length > 0)
78
+ .slice(0, HOSTED_ERROR_STACK_LINE_COUNT);
79
+ const text = lines.join("\n");
80
+ return text.length > HOSTED_ERROR_SNIPPET_MAX_CHARS
81
+ ? `${text.slice(0, HOSTED_ERROR_SNIPPET_MAX_CHARS)}…`
82
+ : text;
83
+ }
84
+ return error.message.length > HOSTED_ERROR_SNIPPET_MAX_CHARS
85
+ ? `${error.message.slice(0, HOSTED_ERROR_SNIPPET_MAX_CHARS)}…`
86
+ : error.message;
87
+ }
88
+ const text = String(error);
89
+ if (text.length === 0) {
90
+ return "";
91
+ }
92
+ return text.length > HOSTED_ERROR_SNIPPET_MAX_CHARS
93
+ ? `${text.slice(0, HOSTED_ERROR_SNIPPET_MAX_CHARS)}…`
94
+ : text;
95
+ }
96
+ export function hostedExecutionDiagPath(stateRoot) {
97
+ return join(stateRoot, HOSTED_EXECUTION_DIAG_FILENAME);
98
+ }
99
+ export function abortReasonFromTurnStatus(status, message) {
100
+ if (status === "finished") {
101
+ return undefined;
102
+ }
103
+ if (status === "cancelled") {
104
+ return message !== undefined && /abort/i.test(message)
105
+ ? "signal_abort"
106
+ : "runner_cancelled";
107
+ }
108
+ return "runner_error";
109
+ }
110
+ export function parseHostedExecutionDiag(raw) {
111
+ if (raw.length === 0 || raw.length > HOSTED_EXECUTION_DIAG_MAX_BYTES) {
112
+ return undefined;
113
+ }
114
+ let parsed;
115
+ try {
116
+ parsed = JSON.parse(raw);
117
+ }
118
+ catch (_a) {
119
+ return undefined;
120
+ }
121
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
122
+ return undefined;
123
+ }
124
+ const body = parsed;
125
+ if (Object.keys(body).some((key) => !DIAG_KEYS.has(key))) {
126
+ return undefined;
127
+ }
128
+ if (body.v !== HOSTED_EXECUTION_DIAG_VERSION ||
129
+ typeof body.executionId !== "string" ||
130
+ body.executionId.length === 0 ||
131
+ body.executionId.length > 64 ||
132
+ typeof body.writtenAt !== "string" ||
133
+ body.writtenAt.length === 0 ||
134
+ body.writtenAt.length > 64 ||
135
+ typeof body.sessionPublicId !== "string" ||
136
+ body.sessionPublicId.length === 0 ||
137
+ body.sessionPublicId.length > 128 ||
138
+ typeof body.sessionId !== "string" ||
139
+ body.sessionId.length > 128 ||
140
+ typeof body.turnStatus !== "string" ||
141
+ body.turnStatus.length === 0 ||
142
+ body.turnStatus.length > 64 ||
143
+ typeof body.durationMs !== "number" ||
144
+ !Number.isFinite(body.durationMs) ||
145
+ body.durationMs < 0) {
146
+ return undefined;
147
+ }
148
+ const message = boundedOptionalString(body.message, 1024);
149
+ const stack = boundedOptionalString(body.stack, HOSTED_ERROR_SNIPPET_MAX_CHARS);
150
+ const requestId = boundedOptionalString(body.requestId, 128);
151
+ const abortReason = body.abortReason === undefined
152
+ ? undefined
153
+ : typeof body.abortReason === "string" &&
154
+ ABORT_REASONS.has(body.abortReason)
155
+ ? body.abortReason
156
+ : undefined;
157
+ if (body.abortReason !== undefined && abortReason === undefined) {
158
+ return undefined;
159
+ }
160
+ if (body.signalAborted !== undefined &&
161
+ typeof body.signalAborted !== "boolean") {
162
+ return undefined;
163
+ }
164
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ v: HOSTED_EXECUTION_DIAG_VERSION, executionId: body.executionId, writtenAt: body.writtenAt, sessionPublicId: body.sessionPublicId, sessionId: body.sessionId, turnStatus: body.turnStatus, durationMs: body.durationMs }, (message === undefined ? {} : { message })), (stack === undefined ? {} : { stack })), (body.signalAborted === true ? { signalAborted: true } : {})), (requestId === undefined ? {} : { requestId })), (abortReason === undefined ? {} : { abortReason }));
165
+ }
166
+ /**
167
+ * Overwrite the per-execution diag file. Soft-fail: a write error must not
168
+ * change the hosted-execution HTTP reply.
169
+ */
170
+ export function writeHostedExecutionDiag(stateRoot, diag) {
171
+ return __awaiter(this, void 0, void 0, function* () {
172
+ const path = hostedExecutionDiagPath(stateRoot);
173
+ const tmp = `${path}.${randomBytes(8).toString("hex")}.tmp`;
174
+ try {
175
+ yield mkdir(stateRoot, { recursive: true });
176
+ const serialized = JSON.stringify(diag);
177
+ const body = serialized.length > HOSTED_EXECUTION_DIAG_MAX_BYTES
178
+ ? JSON.stringify(Object.assign(Object.assign({}, diag), { stack: undefined, message: boundedOptionalString(diag.message, 256) }))
179
+ : serialized;
180
+ yield writeFile(tmp, body, "utf8");
181
+ yield rename(tmp, path);
182
+ }
183
+ catch (_a) {
184
+ yield unlink(tmp).catch(() => undefined);
185
+ }
186
+ });
187
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"http-channel.d.ts","sourceRoot":"","sources":["../../src/internal/http-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAEV,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,aAAa,EACd,MAAM,aAAa,CAAC;AAIrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAQ7B,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,kCAAkC,CAAC,EAAE,OAAO,CAAC;IAC7C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC,GAAG,WAAW,EAAE,CAkZhB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GACA,QAAQ,GAAG,SAAS,CAiBtB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,OAAO,EACb,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAO,GAC/D,QAAQ,CAQV;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,QAAQ,CAEV;AAoGD,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAc9C"}
1
+ {"version":3,"file":"http-channel.d.ts","sourceRoot":"","sources":["../../src/internal/http-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAEV,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,aAAa,EACd,MAAM,aAAa,CAAC;AAIrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAQ7B,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,kCAAkC,CAAC,EAAE,OAAO,CAAC;IAC7C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC,GAAG,WAAW,EAAE,CA2fhB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GACA,QAAQ,GAAG,SAAS,CAiBtB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,OAAO,EACb,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAO,GAC/D,QAAQ,CAQV;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,QAAQ,CAEV;AAoGD,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAc9C"}
@@ -22,7 +22,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  import { samePrincipal } from "./auth.js";
23
23
  import { formatContinuationToken, parseContinuationToken } from "./ids.js";
24
24
  import { isLoopbackAddress } from "./net.js";
25
- import { ApprovalInterruptedError, ApprovalNotFoundError, HTTP_CHANNEL_ID, SessionAuthError, } from "./session-engine.js";
25
+ import { ApprovalInterruptedError, ApprovalNotFoundError, AuthInterruptedError, AuthNotFoundError, HTTP_CHANNEL_ID, SessionAuthError, } from "./session-engine.js";
26
26
  import { eventsUrlForSession, playgroundUrlForSession, } from "./session-urls.js";
27
27
  const SESSION_ID_HEADER = "x-agent-serve-session-id";
28
28
  export function buildHttpChannelRoutes(args) {
@@ -48,12 +48,15 @@ export function buildHttpChannelRoutes(args) {
48
48
  if (body === undefined || typeof body.message !== "string") {
49
49
  return errorResponse(400, "invalid_request", "Expected a JSON body with a string `message`.");
50
50
  }
51
+ if (body.asOf !== undefined && typeof body.asOf !== "string") {
52
+ return errorResponse(400, "invalid_request", "`asOf` must be an ISO-8601 instant with a timezone when provided.");
53
+ }
51
54
  const message = yield transformMessage(body.message, ctx.auth);
52
55
  const workspaceFiles = readWorkspaceFiles(body.workspaceFiles);
53
56
  // Per-session cloud attach (create only). Eval harness uses this to pin
54
57
  // fixture repos without putting them on the agent's default cloud.repos.
55
58
  const cloud = readCloudOptions(body.cloud);
56
- const session = yield engine.send(HTTP_CHANNEL_ID, message, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ auth: ctx.auth }, (typeof body.title === "string" ? { title: body.title } : {})), (body.purpose === "eval" ? { purpose: "eval" } : {})), (body.dryRun === true ? { dryRun: true } : {})), (workspaceFiles === undefined ? {} : { workspaceFiles })), (cloud === undefined ? {} : { cloud })));
59
+ const session = yield engine.send(HTTP_CHANNEL_ID, message, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ auth: ctx.auth }, (typeof body.title === "string" ? { title: body.title } : {})), (body.purpose === "eval" ? { purpose: "eval" } : {})), (body.dryRun === true ? { dryRun: true } : {})), { asOf: body.asOf }), (workspaceFiles === undefined ? {} : { workspaceFiles })), (cloud === undefined ? {} : { cloud })));
57
60
  return jsonResponse({
58
61
  ok: true,
59
62
  sessionId: session.id,
@@ -324,6 +327,84 @@ export function buildHttpChannelRoutes(args) {
324
327
  return jsonResponse({ ok: true, interrupted }, { headers: { [SESSION_ID_HEADER]: sessionId } });
325
328
  }),
326
329
  };
330
+ const listAuths = {
331
+ method: "GET",
332
+ pattern: `${base}/v1/session/:sessionId/auths`,
333
+ auth,
334
+ handler: (_request, ctx) => __awaiter(this, void 0, void 0, function* () {
335
+ var _a;
336
+ const sessionId = (_a = ctx.params.sessionId) !== null && _a !== void 0 ? _a : "";
337
+ const record = yield engine.getOrRestoreSession(sessionId);
338
+ if (record === undefined) {
339
+ return errorResponse(404, "session_not_found", `Unknown session ${sessionId}.`);
340
+ }
341
+ const ownership = requireSessionOwner(record, ctx.auth, {
342
+ relax: relaxSessionReadAuth,
343
+ beyondLoopback: relaxSessionReadAuthBeyondLoopback,
344
+ requestIp: ctx.requestIp,
345
+ });
346
+ if (ownership !== undefined) {
347
+ return ownership;
348
+ }
349
+ const pending = yield engine.listPendingAuths(sessionId);
350
+ return jsonResponse({ ok: true, sessionId, pending });
351
+ }),
352
+ };
353
+ const resolveAuth = {
354
+ method: "POST",
355
+ pattern: `${base}/v1/session/:sessionId/auths/:callId`,
356
+ auth,
357
+ handler: (request, ctx) => __awaiter(this, void 0, void 0, function* () {
358
+ var _a;
359
+ var _b, _c;
360
+ const sessionId = (_b = ctx.params.sessionId) !== null && _b !== void 0 ? _b : "";
361
+ const callId = (_c = ctx.params.callId) !== null && _c !== void 0 ? _c : "";
362
+ const record = yield engine.getOrRestoreSession(sessionId);
363
+ if (record === undefined) {
364
+ return errorResponse(404, "session_not_found", `Unknown session ${sessionId}.`);
365
+ }
366
+ const bridgeSlackAuth = relaxSessionApprovalAuth === true &&
367
+ ((_a = record.auth) === null || _a === void 0 ? void 0 : _a.authenticator) === "slack" &&
368
+ (relaxSessionReadAuthBeyondLoopback === true ||
369
+ (typeof ctx.requestIp === "string" &&
370
+ isLoopbackAddress(ctx.requestIp)));
371
+ const ownership = requireSessionOwner(record, ctx.auth, {
372
+ relax: bridgeSlackAuth,
373
+ beyondLoopback: relaxSessionReadAuthBeyondLoopback,
374
+ requestIp: ctx.requestIp,
375
+ });
376
+ if (ownership !== undefined) {
377
+ return ownership;
378
+ }
379
+ const body = yield readJsonObject(request);
380
+ const decision = body === null || body === void 0 ? void 0 : body.decision;
381
+ if (decision !== "approve" && decision !== "deny") {
382
+ return errorResponse(400, "invalid_request", 'Expected a JSON body with `decision`: "approve" | "deny".');
383
+ }
384
+ try {
385
+ const pending = yield engine.resolveAuth(sessionId, callId, decision, ctx.auth, bridgeSlackAuth ? { asSessionOwner: true } : undefined);
386
+ return jsonResponse({
387
+ ok: true,
388
+ sessionId,
389
+ callId,
390
+ decision,
391
+ connection: pending.connection,
392
+ });
393
+ }
394
+ catch (error) {
395
+ if (error instanceof AuthNotFoundError) {
396
+ return errorResponse(404, "auth_not_found", error.message);
397
+ }
398
+ if (error instanceof AuthInterruptedError) {
399
+ return errorResponse(409, "auth_interrupted", error.message);
400
+ }
401
+ if (error instanceof SessionAuthError) {
402
+ return errorResponse(403, "forbidden", error.message);
403
+ }
404
+ throw error;
405
+ }
406
+ }),
407
+ };
327
408
  return [
328
409
  createSession,
329
410
  followUp,
@@ -333,6 +414,8 @@ export function buildHttpChannelRoutes(args) {
333
414
  cost,
334
415
  listApprovals,
335
416
  resolveApproval,
417
+ listAuths,
418
+ resolveAuth,
336
419
  ];
337
420
  }
338
421
  export function requireSessionOwner(record, caller, options) {