@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
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Deployment-secret upsert for host MCP OAuth (`mcp oauth --store` and
3
+ * hosted Connect). File writes stay on FileMcpOAuthStore / the OAuth
4
+ * provider. Resolve the `--store` client at persist time so v2 freeze
5
+ * bind can drop the key after listen.
6
+ */
7
+
8
+ import type { OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
9
+ import { AGENT_SERVE_DEPLOYMENT_ID_ENV_VAR } from "../storage-backends/cursor-hosted.js";
10
+ import {
11
+ cursorExternalApiUrl,
12
+ resolveApiKeySync,
13
+ } from "./cursor/credentials.js";
14
+ import {
15
+ AgentServeDeployClient,
16
+ parseAgentServeMcpGatewayUrl,
17
+ } from "./deploy-client.js";
18
+ import { mcpOauthSecretNames } from "./mcp-oauth.js";
19
+
20
+ export type McpOauthSecretsClient = {
21
+ setSecrets(args: {
22
+ teamId: number;
23
+ slug: string;
24
+ secrets: Array<{ name: string; value: string }>;
25
+ }): Promise<string[]>;
26
+ };
27
+
28
+ export type McpOauthSecretsTarget = {
29
+ client: McpOauthSecretsClient;
30
+ teamId: number;
31
+ slug: string;
32
+ };
33
+
34
+ function mcpOauthSecretsPayload(args: {
35
+ connection: string;
36
+ tokens: OAuthTokens;
37
+ clientId?: string;
38
+ }): Array<{ name: string; value: string }> {
39
+ const names = mcpOauthSecretNames(args.connection);
40
+ const secrets: Array<{ name: string; value: string }> = [
41
+ { name: names.accessToken, value: args.tokens.access_token },
42
+ ];
43
+ const refresh = args.tokens.refresh_token?.trim();
44
+ if (refresh !== undefined && refresh !== "") {
45
+ secrets.push({ name: names.refreshToken, value: refresh });
46
+ }
47
+ const clientId = args.clientId?.trim();
48
+ if (clientId !== undefined && clientId !== "") {
49
+ secrets.push({ name: names.clientId, value: clientId });
50
+ }
51
+ return secrets;
52
+ }
53
+
54
+ export async function upsertHostMcpOauthSecrets(args: {
55
+ connection: string;
56
+ tokens: OAuthTokens;
57
+ clientId?: string;
58
+ target: McpOauthSecretsTarget;
59
+ }): Promise<string[]> {
60
+ const payload = mcpOauthSecretsPayload(args);
61
+ if (payload.length === 0) {
62
+ return [];
63
+ }
64
+ return await args.target.client.setSecrets({
65
+ teamId: args.target.teamId,
66
+ slug: args.target.slug,
67
+ secrets: payload,
68
+ });
69
+ }
70
+
71
+ export type ResolveHostedMcpOauthSecretsArgs = {
72
+ slug?: string;
73
+ team?: string;
74
+ apiKey?: string;
75
+ cloudToolsUrl?: string;
76
+ env?: NodeJS.ProcessEnv;
77
+ };
78
+
79
+ /**
80
+ * Bind the CLI `--store` client when this process is a hosted engine
81
+ * (`AGENT_SERVE_DEPLOYMENT_ID`) and a live API key is present.
82
+ * Self-hosted / no deployment / unsigned: undefined.
83
+ */
84
+ export function resolveHostedMcpOauthSecretsTarget(
85
+ args: ResolveHostedMcpOauthSecretsArgs = {}
86
+ ): McpOauthSecretsTarget | undefined {
87
+ const env = args.env ?? process.env;
88
+ const deploymentId = env[AGENT_SERVE_DEPLOYMENT_ID_ENV_VAR]?.trim();
89
+ if (deploymentId === undefined || deploymentId === "") {
90
+ return undefined;
91
+ }
92
+ const resolved = resolveApiKeySync(
93
+ args.apiKey === undefined ? undefined : { apiKey: args.apiKey }
94
+ );
95
+ if (resolved === undefined) {
96
+ return undefined;
97
+ }
98
+ const fromUrl =
99
+ args.cloudToolsUrl === undefined
100
+ ? undefined
101
+ : parseAgentServeMcpGatewayUrl(args.cloudToolsUrl);
102
+ const slug =
103
+ args.slug !== undefined && args.slug !== "" ? args.slug : fromUrl?.slug;
104
+ const teamId = parseTeamId(args.team) ?? fromUrl?.teamId;
105
+ if (slug === undefined || teamId === undefined) {
106
+ return undefined;
107
+ }
108
+ return {
109
+ client: new AgentServeDeployClient({
110
+ backendUrl: cursorExternalApiUrl(),
111
+ apiKey: resolved.apiKey,
112
+ }),
113
+ teamId,
114
+ slug,
115
+ };
116
+ }
117
+
118
+ function parseTeamId(team: string | undefined): number | undefined {
119
+ if (team === undefined || team === "") {
120
+ return undefined;
121
+ }
122
+ const teamId = Number.parseInt(team, 10);
123
+ if (!Number.isInteger(teamId) || teamId <= 0) {
124
+ return undefined;
125
+ }
126
+ return teamId;
127
+ }
@@ -411,13 +411,25 @@ export class HostMcpOAuthProvider implements OAuthClientProvider {
411
411
  }
412
412
  }
413
413
 
414
+ function clientForRedirect(
415
+ info: OAuthClientInformationFull | undefined,
416
+ redirectUrl: string
417
+ ): OAuthClientInformationFull | undefined {
418
+ if (info === undefined || !info.redirect_uris.includes(redirectUrl)) {
419
+ return undefined;
420
+ }
421
+ return info;
422
+ }
423
+
414
424
  export async function createHostMcpOAuthProvider(args: {
415
425
  identifier: string;
416
426
  resourceUrl: string;
417
427
  store?: FileMcpOAuthStore;
418
428
  onRedirect?: (url: URL) => void;
429
+ redirectUrl?: string;
419
430
  }): Promise<HostMcpOAuthProvider> {
420
431
  const store = args.store ?? new FileMcpOAuthStore();
432
+ const redirectUrl = args.redirectUrl ?? MCP_OAUTH_CALLBACK_URL;
421
433
  const [fileTokens, fileClient, omitResourceIndicator] = await Promise.all([
422
434
  store.loadTokens(args.identifier, args.resourceUrl),
423
435
  store.loadClientInformation(args.identifier, args.resourceUrl),
@@ -427,8 +439,12 @@ export async function createHostMcpOAuthProvider(args: {
427
439
  identifier: args.identifier,
428
440
  resourceUrl: args.resourceUrl,
429
441
  store,
442
+ redirectUrl,
430
443
  tokens: fileTokens ?? tokensFromEnv(args.identifier),
431
- clientInformation: fileClient ?? clientIdFromEnv(args.identifier),
444
+ clientInformation: clientForRedirect(
445
+ fileClient ?? clientIdFromEnv(args.identifier),
446
+ redirectUrl
447
+ ),
432
448
  onRedirect: args.onRedirect,
433
449
  omitResourceIndicator,
434
450
  });
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The inert KV half of hosted v2 storage.
3
+ *
4
+ * The control-plane KV proxy (`/internal/agent-serve/storage/*`) authorizes a
5
+ * request by mapping the caller's pod service account to a row in the v1
6
+ * deployment table. Architecture v2 registers its deployments in the factory
7
+ * control plane instead, so every proxy call from a v2 pod answers
8
+ * `403 No Agent Serve deployment is bound to this service account`. The
9
+ * lazy-restore path deliberately propagates read failures (a store outage must
10
+ * not read as "unknown continuation token"), so those 403s fail follow-up
11
+ * deliveries outright.
12
+ *
13
+ * This backend stands in for the proxy until it can resolve v2 deployments:
14
+ * writes are dropped, reads are definitive misses, and lists are empty. It is
15
+ * paired with the framework file store (see framework-file-storage.ts), which
16
+ * authorizes by store source id rather than by deployment row and therefore
17
+ * still carries session records, event transcripts, and the continuation
18
+ * index — the state sessions are restored from.
19
+ *
20
+ * Author KV is the one thing that must not silently accept writes here, since
21
+ * handlers read their own writes back. {@link AUTHOR_KV_UNSUPPORTED} marks the
22
+ * definition so `ctx.host.kv` falls back to `--state-root` disk instead, the
23
+ * same fallback a deployment with no configured backend gets.
24
+ */
25
+
26
+ import type { StorageConfig } from "../storage.js";
27
+ import type { JsonValue } from "../types.js";
28
+
29
+ /**
30
+ * Marker stamped on a definition whose KV core cannot serve `ctx.host.kv`,
31
+ * even though `get` is present for framework session state. Explicit
32
+ * `unique symbol` annotation required for `--isolatedDeclarations` (TS9010).
33
+ */
34
+ export const AUTHOR_KV_UNSUPPORTED: unique symbol = Symbol.for(
35
+ "@cursor/july.storage.author-kv-unsupported"
36
+ );
37
+
38
+ /** True when `value` was built from {@link nullKvStorage}. */
39
+ export function isAuthorKvUnsupported(value: unknown): boolean {
40
+ return (
41
+ typeof value === "object" &&
42
+ value !== null &&
43
+ (value as Record<symbol, unknown>)[AUTHOR_KV_UNSUPPORTED] === true
44
+ );
45
+ }
46
+
47
+ type NullKvStorageMethods = Required<
48
+ Pick<StorageConfig, "put" | "get" | "delete" | "list">
49
+ > & {
50
+ readonly [AUTHOR_KV_UNSUPPORTED]: true;
51
+ };
52
+
53
+ /**
54
+ * A KV core that stores nothing. `get` resolving `undefined` is honest here
55
+ * rather than dangerous: nothing was ever written, so a miss cannot shadow a
56
+ * session that exists elsewhere.
57
+ *
58
+ * No `cas` group and no `listNewest`: conditional writes over a store that
59
+ * forgets would report a lock acquired, and write-time ordering means nothing
60
+ * without writes.
61
+ */
62
+ export function nullKvStorage(): NullKvStorageMethods {
63
+ return {
64
+ [AUTHOR_KV_UNSUPPORTED]: true,
65
+ put(): void {},
66
+ get(): JsonValue | undefined {
67
+ return undefined;
68
+ },
69
+ delete(): void {},
70
+ list(): [] {
71
+ return [];
72
+ },
73
+ };
74
+ }
@@ -284,6 +284,36 @@ export function createOtelCollector(
284
284
  );
285
285
  return;
286
286
  }
287
+ case "action.auth_requested": {
288
+ ensureTurn(event, session, startTime)
289
+ ?.tools.get(event.data.callId)
290
+ ?.addEvent("auth_requested", undefined, startTime);
291
+ emitLog(
292
+ "action.auth_requested",
293
+ SeverityNumber.INFO,
294
+ attrs({
295
+ ...baseLog(event, session),
296
+ "cursor.tool.name": event.data.toolName,
297
+ "agent_sdk.call_id": event.data.callId,
298
+ "agent_sdk.mcp_connection": event.data.connection,
299
+ })
300
+ );
301
+ return;
302
+ }
303
+ case "action.auth_resolved": {
304
+ ensureTurn(event, session, startTime)
305
+ ?.tools.get(event.data.callId)
306
+ ?.addEvent(
307
+ "auth_resolved",
308
+ attrs({
309
+ "agent_sdk.decision": event.data.decision,
310
+ "agent_sdk.decision_by": event.data.by,
311
+ "agent_sdk.mcp_connection": event.data.connection,
312
+ }),
313
+ startTime
314
+ );
315
+ return;
316
+ }
287
317
  case "action.result": {
288
318
  const turn = ensureTurn(event, session, startTime);
289
319
  const span = turn?.tools.get(event.data.callId);
@@ -50,6 +50,7 @@ import type {
50
50
  ReminderInfo,
51
51
  ServeOptions,
52
52
  } from "../types.js";
53
+ import { InvalidAsOfError, VacuousTimeArgsError } from "./as-of.js";
53
54
  import { V2EngineError } from "./continuation-identity.js";
54
55
  import { selectConversationMirror } from "./conversation-mirror.js";
55
56
  import {
@@ -109,6 +110,7 @@ import {
109
110
  } from "./handleAgentServeTrigger.js";
110
111
  import { createHostPlatforms, warmupHostGitHubAuth } from "./host-platforms.js";
111
112
  import { registerHostedDeliveryRoute } from "./hosted-delivery.js";
113
+ import { hostedErrorStackSnippet } from "./hosted-execution-diag.js";
112
114
  import {
113
115
  buildHttpChannelRoutes,
114
116
  errorResponse,
@@ -130,6 +132,11 @@ import {
130
132
  MCP_ENDPOINT_PATH,
131
133
  TOOL_MCP_ENDPOINT_PATH,
132
134
  } from "./mcp-endpoint.js";
135
+ import {
136
+ mcpOauthServeCallbackPath,
137
+ mcpOauthServeCallbackUrl,
138
+ } from "./mcp-oauth-on-demand.js";
139
+ import type { McpOauthSecretsTarget } from "./mcp-oauth-persist.js";
133
140
  import { isLoopbackAddress } from "./net.js";
134
141
  import { createOtelCollector, type OtelCollector } from "./otel/collector.js";
135
142
  import { pickAuthoredOtel, resolveOtelConfig } from "./otel/config.js";
@@ -181,6 +188,11 @@ import {
181
188
  UnknownToolError,
182
189
  WorkspaceUnavailableError,
183
190
  } from "./session-engine.js";
191
+ import {
192
+ registerSessionRunFatalFlush,
193
+ selectSessionRunLogStore,
194
+ unregisterSessionRunFatalFlush,
195
+ } from "./session-run-log.js";
184
196
  import { sessionUrlsForRequest } from "./session-urls.js";
185
197
  import { catalogDetailEntry, catalogListEntry } from "./tool-catalog.js";
186
198
 
@@ -240,6 +252,10 @@ function isV2Project(project: { agent: { architecture?: string } }): boolean {
240
252
  export interface StartServerInternalOptions {
241
253
  /** Test seam: replace the Cursor SDK runner (integration tests). */
242
254
  runner?: AgentRunner;
255
+ /** Test seam: bind the `--store` secrets client for on-demand MCP OAuth. */
256
+ mcpOauthSecrets?: McpOauthSecretsTarget;
257
+ /** Test seam: persist hosted-execution run logs without a live store. */
258
+ sessionRunLog?: ReturnType<typeof selectSessionRunLogStore>;
243
259
  }
244
260
 
245
261
  /**
@@ -525,6 +541,20 @@ export async function startServer(
525
541
  mounts.length === 1 && mounts[0] !== undefined
526
542
  ? selectConversationMirror({ project: mounts[0].project, logger })
527
543
  : undefined;
544
+ const sessionRunLog =
545
+ options.sessionRunLog ??
546
+ (mounts.length === 1 && mounts[0] !== undefined
547
+ ? selectSessionRunLogStore({
548
+ project: mounts[0].project,
549
+ logger,
550
+ snapshotLogs: () => logRing.since(),
551
+ })
552
+ : undefined);
553
+ if (sessionRunLog !== undefined) {
554
+ registerSessionRunFatalFlush((error) =>
555
+ sessionRunLog.flushProcessDeath("uncaught_exception", error)
556
+ );
557
+ }
528
558
  const sdkRunner =
529
559
  options.runner ??
530
560
  new CursorSdkRunner({
@@ -647,6 +677,12 @@ export async function startServer(
647
677
  otel: otelCollector,
648
678
  otelMeter: otelRuntime?.meter,
649
679
  });
680
+ engine.oauthCallbackHub.secrets = options.mcpOauthSecrets;
681
+ engine.oauthCallbackHub.secretsBind = {
682
+ slug: slug === "" ? undefined : slug,
683
+ cloudToolsUrl: options.cloudToolsUrl,
684
+ };
685
+ engine.oauthCallbackHub.logger = logger;
650
686
  // Rehydrate sessions from the authored storage sink before any
651
687
  // channel or route can address them (continuation tokens must resolve).
652
688
  await engine.restoreStoredSessions();
@@ -732,6 +768,8 @@ export async function startServer(
732
768
  multi,
733
769
  logger,
734
770
  logRing,
771
+ diagStateRoot: baseStateRoot,
772
+ sessionRunLog,
735
773
  ...(options.authToken === undefined
736
774
  ? {}
737
775
  : { authToken: options.authToken }),
@@ -762,6 +800,8 @@ export async function startServer(
762
800
  },
763
801
  resolveApproval: (sessionId, callId, decision, auth) =>
764
802
  engine.resolveApproval(sessionId, callId, decision, auth),
803
+ resolveAuth: (sessionId, callId, decision, auth) =>
804
+ engine.resolveAuth(sessionId, callId, decision, auth),
765
805
  hasContinuationSession: (continuationToken) =>
766
806
  engine.hasContinuationSession(channel.id, continuationToken),
767
807
  isContinuationBusy: (continuationToken) =>
@@ -1013,6 +1053,7 @@ export async function startServer(
1013
1053
  const address = server.address() as AddressInfo;
1014
1054
  const displayHost = host === "0.0.0.0" || host === "::" ? "127.0.0.1" : host;
1015
1055
  const url = `http://${displayHost}:${boundPort}`;
1056
+ const oauthOrigin = (options.publicUrl ?? url).replace(/\/$/, "");
1016
1057
 
1017
1058
  // Resolve peer + Cursor account MCP connections now that the listen port is
1018
1059
  // known (see resolved-connections.ts for the URL/runtime rules).
@@ -1039,6 +1080,20 @@ export async function startServer(
1039
1080
  if (resolved.length > 0) {
1040
1081
  runtime.engine.setResolvedConnections(resolved);
1041
1082
  }
1083
+ const oauthBase = runtime.slug === "" ? "" : `/${runtime.slug}`;
1084
+ runtime.engine.setMcpOauthCallbackUrl(
1085
+ mcpOauthServeCallbackUrl(oauthOrigin, oauthBase)
1086
+ );
1087
+ if (accountBridge !== undefined && accountRefs !== undefined) {
1088
+ const bridge = accountBridge;
1089
+ runtime.engine.setCursorAccountAuthProbe(async (connection) => {
1090
+ const ref = accountRefs.find((entry) => entry.name === connection);
1091
+ if (ref === undefined) {
1092
+ return undefined;
1093
+ }
1094
+ return await bridge.probeAuthUrl(ref);
1095
+ });
1096
+ }
1042
1097
  const hasServerTools = runtime.project.agent.tools.some(
1043
1098
  (tool) => tool.execution === "server"
1044
1099
  );
@@ -1168,6 +1223,10 @@ export async function startServer(
1168
1223
  return runtime.engine.callTool(toolName, input, callOptions);
1169
1224
  },
1170
1225
  close: async () => {
1226
+ if (sessionRunLog !== undefined) {
1227
+ await sessionRunLog.flushProcessDeath("process_exit");
1228
+ unregisterSessionRunFatalFlush();
1229
+ }
1171
1230
  playgroundDev?.stop();
1172
1231
  await cursorDeploymentRelay?.stop();
1173
1232
  await cursorEventRelay?.stop();
@@ -1222,15 +1281,29 @@ function mountAgentRoutes(
1222
1281
  multi: boolean;
1223
1282
  logger: (line: string) => void;
1224
1283
  logRing: LogRing;
1284
+ sessionRunLog?: ReturnType<typeof selectSessionRunLogStore>;
1225
1285
  authToken?: string;
1226
1286
  allowAnonymous?: boolean;
1227
1287
  /** Cursor account bridge + this mount's account MCP connections, when authored. */
1228
1288
  accountBridge?: CursorAccountMcpBridge;
1229
1289
  accountRefs?: CursorAccountConnectionRef[];
1290
+ /**
1291
+ * Serve `--state-root`. Hosted-execution writes `hosted-execution.json`
1292
+ * here so the Temporal host can read a stable path after the POST.
1293
+ */
1294
+ diagStateRoot?: string;
1230
1295
  }
1231
1296
  ): void {
1232
1297
  const { slug, project, engine, scheduleRunner, reminderRunner } = runtime;
1233
- const { dev, playground, noControlPlane, multi, logger, logRing } = args;
1298
+ const {
1299
+ dev,
1300
+ playground,
1301
+ noControlPlane,
1302
+ multi,
1303
+ logger,
1304
+ logRing,
1305
+ sessionRunLog,
1306
+ } = args;
1234
1307
  // "" (single) -> "/v1/..."; "my-agent" (multi) -> "/my-agent/v1/...".
1235
1308
  const base = slug === "" ? "" : `/${slug}`;
1236
1309
 
@@ -1288,6 +1361,13 @@ function mountAgentRoutes(
1288
1361
  }),
1289
1362
  drainSessionDurability: (sessionId) =>
1290
1363
  engine.drainSessionDurability(sessionId),
1364
+ ...(args.diagStateRoot === undefined
1365
+ ? {}
1366
+ : { stateRoot: args.diagStateRoot }),
1367
+ ...(sessionRunLog === undefined
1368
+ ? {}
1369
+ : { persistSessionRun: (document) => sessionRunLog.persist(document) }),
1370
+ snapshotLogs: () => logRing.since(),
1291
1371
  });
1292
1372
  }
1293
1373
  // Playground lists/opens Slack (and other channel) sessions across
@@ -1303,6 +1383,13 @@ function mountAgentRoutes(
1303
1383
  // tools (Slack principals never match local/anonymous HTTP auth).
1304
1384
  const relaxSessionApprovalAuth = relaxSessionReadAuth;
1305
1385
 
1386
+ router.add({
1387
+ method: "GET",
1388
+ pattern: `${base}${mcpOauthServeCallbackPath()}`,
1389
+ auth: "none",
1390
+ handler: (request) => engine.oauthCallbackHub.handleCallback(request),
1391
+ });
1392
+
1306
1393
  router.add({
1307
1394
  method: "GET",
1308
1395
  pattern: `${base}/v1/health`,
@@ -1387,11 +1474,56 @@ function mountAgentRoutes(
1387
1474
  },
1388
1475
  });
1389
1476
 
1477
+ // v2 only: one session-level hosted-execution log on the framework
1478
+ // store. Distinct from GET /v1/logs (process-wide ring). Keyed by the
1479
+ // factory session public id so an execute_throw that never minted a
1480
+ // July session is still readable after the pod parks.
1481
+ if (isV2Project(project) && sessionRunLog !== undefined) {
1482
+ router.add({
1483
+ method: "GET",
1484
+ pattern: `${base}/v1/session/:sessionId/runs`,
1485
+ auth: httpAuth,
1486
+ handler: async (_request, ctx) => {
1487
+ const sessionId = ctx.params.sessionId ?? "";
1488
+ if (sessionId.length === 0 || sessionId.includes("/")) {
1489
+ return errorResponse(
1490
+ 400,
1491
+ "invalid_request",
1492
+ "Expected a session id."
1493
+ );
1494
+ }
1495
+ const record = await engine.getOrRestoreSession(sessionId);
1496
+ if (record === undefined) {
1497
+ return errorResponse(
1498
+ 404,
1499
+ "session_not_found",
1500
+ `Unknown session ${sessionId}.`
1501
+ );
1502
+ }
1503
+ const ownership = requireSessionOwner(record, ctx.auth, {
1504
+ relax: relaxSessionReadAuth,
1505
+ beyondLoopback: relaxSessionReadAuthBeyondLoopback,
1506
+ requestIp: ctx.requestIp,
1507
+ });
1508
+ if (ownership !== undefined) {
1509
+ return ownership;
1510
+ }
1511
+ const document = await sessionRunLog.read(sessionId);
1512
+ return jsonResponse({
1513
+ sessionId,
1514
+ updatedAt: document?.updatedAt,
1515
+ lastFailure: document?.lastFailure ?? null,
1516
+ executions: document?.executions ?? [],
1517
+ });
1518
+ },
1519
+ });
1520
+ }
1521
+
1390
1522
  router.add({
1391
1523
  method: "GET",
1392
1524
  pattern: `${base}/v1/sessions`,
1393
1525
  auth: httpAuth,
1394
- handler: async (_request, ctx) => {
1526
+ handler: async (request, ctx) => {
1395
1527
  // Same gate as requireSessionOwner / relaxSessionReadAuth: never with
1396
1528
  // bearer or custom channel auth (strict per-principal isolation).
1397
1529
  // `--allow-anonymous` alone is a shared-principal trust boundary (corp
@@ -1401,9 +1533,14 @@ function mountAgentRoutes(
1401
1533
  (relaxSessionReadAuthBeyondLoopback ||
1402
1534
  (typeof ctx.requestIp === "string" &&
1403
1535
  isLoopbackAddress(ctx.requestIp)));
1404
- const listed = await engine.listSessionsWithSource(ctx.auth, {
1405
- includeAll,
1406
- });
1536
+ // `?latest=1` only the newest visible session. Clients binding a
1537
+ // default session (agsh) do not need the whole list, and on hosted
1538
+ // storage the whole list is a database scan.
1539
+ const latest = new URL(request.url).searchParams.get("latest");
1540
+ const listed =
1541
+ latest === "1" || latest === "true"
1542
+ ? await engine.latestSessionWithSource(ctx.auth, { includeAll })
1543
+ : await engine.listSessionsWithSource(ctx.auth, { includeAll });
1407
1544
  return jsonResponse({
1408
1545
  sessions: listed.sessions,
1409
1546
  source: listed.source,
@@ -1613,23 +1750,22 @@ function mountAgentRoutes(
1613
1750
  return binding.errorResponse;
1614
1751
  }
1615
1752
  try {
1616
- const catalog = await engine.listCatalogTools({
1753
+ const described = await engine.describeCatalogTool(toolName, {
1617
1754
  auth: ctx.auth,
1618
1755
  ...binding,
1619
1756
  });
1620
- const tool = catalog.tools.find((t) => t.name === toolName);
1621
- if (tool === undefined) {
1757
+ if (described.tool === undefined) {
1622
1758
  return jsonResponse(
1623
1759
  {
1624
1760
  ok: false,
1625
1761
  error: "unknown_tool",
1626
1762
  message: `Unknown tool "${toolName}".`,
1627
- availableTools: catalog.tools.map((t) => t.name),
1763
+ availableTools: described.availableTools,
1628
1764
  },
1629
1765
  { status: 404 }
1630
1766
  );
1631
1767
  }
1632
- return jsonResponse(catalogDetailEntry(tool));
1768
+ return jsonResponse(catalogDetailEntry(described.tool));
1633
1769
  } catch (error) {
1634
1770
  if (error instanceof InvalidContinuationTokenError) {
1635
1771
  return errorResponse(
@@ -2779,6 +2915,11 @@ async function handleRequest(
2779
2915
  );
2780
2916
  } else if (error instanceof SessionAuthError) {
2781
2917
  response = errorResponse(403, "forbidden", error.message);
2918
+ } else if (
2919
+ error instanceof InvalidAsOfError ||
2920
+ error instanceof VacuousTimeArgsError
2921
+ ) {
2922
+ response = errorResponse(400, "invalid_request", error.message);
2782
2923
  } else {
2783
2924
  logger(
2784
2925
  `[agent-sdk] request failed: ${
@@ -2787,7 +2928,14 @@ async function handleRequest(
2787
2928
  : String(error)
2788
2929
  }`
2789
2930
  );
2790
- response = errorResponse(500, "internal_error", "Internal server error.");
2931
+ const snippet = hostedErrorStackSnippet(error);
2932
+ response = errorResponse(
2933
+ 500,
2934
+ "internal_error",
2935
+ snippet.length > 0
2936
+ ? `Internal server error: ${snippet}`
2937
+ : "Internal server error."
2938
+ );
2791
2939
  }
2792
2940
  }
2793
2941