@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,584 @@
1
+ /**
2
+ * Durable hosted-execution run log on the framework file store. **v2 only.**
3
+ *
4
+ * One JSON document per factory session (`ses_…`), with per-execution
5
+ * entries inside. The later customer UI is session-scoped ("why did this
6
+ * session fail?") so a single GET is the read path; continuations are FIFO
7
+ * so last-write-wins merge is safe. Guest-local `hosted-execution.json` and
8
+ * factorydb `last_error` are lossy: the on-disk diag dies with the pod, and
9
+ * the session row only keeps the first 1024 characters of a generic HTTP
10
+ * 500.
11
+ *
12
+ * Process death: persist `running` at turn start so SIGKILL / OOM still
13
+ * leaves a durable leftover. `uncaughtException` / SIGTERM flush the same
14
+ * session key with `processDeath: true` and the real throw. Soft-fail on
15
+ * persist so a store outage never changes the hosted-execution HTTP reply.
16
+ *
17
+ * Keys: {@link storageKeys.sessionRun}.
18
+ */
19
+
20
+ import type { FileSink } from "../files.js";
21
+ import {
22
+ cursorFrameworkStoreSourceId,
23
+ cursorHostedFiles,
24
+ } from "../files-backends/cursor-hosted.js";
25
+ import { storageKeys } from "../storage-protocol.js";
26
+ import type { AgentProject } from "../types.js";
27
+ import { resolveApiKeySync } from "./cursor/credentials.js";
28
+ import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
29
+ import { describeError } from "./describe-error.js";
30
+ import type { HostedExecutionDiagAbortReason } from "./hosted-execution-diag.js";
31
+ import type { LogRingEntry } from "./log-ring.js";
32
+
33
+ export const SESSION_RUN_LOG_VERSION = 1;
34
+ /** Last N log-ring lines kept on each execution. */
35
+ export const SESSION_RUN_LOG_MAX_ENTRIES = 200;
36
+ /** Per-line cap so a runaway logger cannot blow the document. */
37
+ export const SESSION_RUN_LOG_MAX_LINE_CHARS = 4096;
38
+ /** Continuations are FIFO; keep a bounded history for the session UI. */
39
+ export const SESSION_RUN_LOG_MAX_EXECUTIONS = 20;
40
+ const MAX_ERROR_MESSAGE_CHARS = 4096;
41
+ const MAX_ERROR_STACK_CHARS = 16_384;
42
+ const MAX_DOCUMENT_CHARS = 512 * 1024;
43
+ /** Crash-handler flush must not block `process.exit`. */
44
+ export const SESSION_RUN_FATAL_FLUSH_TIMEOUT_MS = 2_000;
45
+
46
+ export type SessionRunAbortReason =
47
+ | HostedExecutionDiagAbortReason
48
+ | "process_exit"
49
+ | "uncaught_exception"
50
+ | "unhandled_rejection";
51
+
52
+ export type SessionRunLogError = {
53
+ name: string;
54
+ message: string;
55
+ stack?: string;
56
+ };
57
+
58
+ export type SessionRunExecution = {
59
+ executionId: string;
60
+ writtenAt: string;
61
+ sessionId: string;
62
+ turnStatus: string;
63
+ durationMs: number;
64
+ abortReason?: SessionRunAbortReason;
65
+ message?: string;
66
+ error?: SessionRunLogError;
67
+ /** True when this entry was flushed from a process-death handler. */
68
+ processDeath?: boolean;
69
+ logs: LogRingEntry[];
70
+ };
71
+
72
+ /**
73
+ * Latest non-success execution, including leftover `running` after the
74
+ * process died without a terminal persist (SIGKILL / OOM). Undefined when
75
+ * the latest execution `turnStatus` is `finished`.
76
+ */
77
+ export type SessionRunLastFailure = {
78
+ executionId: string;
79
+ writtenAt: string;
80
+ turnStatus: string;
81
+ abortReason?: SessionRunAbortReason;
82
+ message?: string;
83
+ error?: SessionRunLogError;
84
+ processDeath?: boolean;
85
+ };
86
+
87
+ /** One document per factory session. The customer UI reads this object. */
88
+ export type SessionRunLogDocument = {
89
+ v: typeof SESSION_RUN_LOG_VERSION;
90
+ sessionPublicId: string;
91
+ updatedAt: string;
92
+ lastFailure?: SessionRunLastFailure;
93
+ executions: SessionRunExecution[];
94
+ };
95
+
96
+ /** Persist input: one execution upserted into the session document. */
97
+ export type SessionRunExecutionWrite = SessionRunExecution & {
98
+ sessionPublicId: string;
99
+ };
100
+
101
+ export interface SessionRunLogStore {
102
+ persist(write: SessionRunExecutionWrite): Promise<void>;
103
+ read(sessionPublicId: string): Promise<SessionRunLogDocument | undefined>;
104
+ /**
105
+ * Upgrade the in-flight `running` claim to a terminal process-death
106
+ * entry. No-op when no execution is active (already terminal, or never
107
+ * started). Soft-fail.
108
+ */
109
+ flushProcessDeath(
110
+ reason: Extract<
111
+ SessionRunAbortReason,
112
+ "process_exit" | "uncaught_exception" | "unhandled_rejection"
113
+ >,
114
+ error?: unknown
115
+ ): Promise<void>;
116
+ }
117
+
118
+ type ActiveExecution = {
119
+ sessionPublicId: string;
120
+ executionId: string;
121
+ sessionId: string;
122
+ startedAt: number;
123
+ };
124
+
125
+ let fatalFlush: ((error: unknown) => Promise<void>) | undefined;
126
+
127
+ /**
128
+ * Install the crash-handler flush used by `bin/agent-serve` on
129
+ * `uncaughtException`. One process, one active hosted serve.
130
+ */
131
+ export function registerSessionRunFatalFlush(
132
+ flush: (error: unknown) => Promise<void>
133
+ ): void {
134
+ fatalFlush = flush;
135
+ }
136
+
137
+ export function unregisterSessionRunFatalFlush(): void {
138
+ fatalFlush = undefined;
139
+ }
140
+
141
+ /**
142
+ * Await the registered crash flush, bounded so a hung store cannot prevent
143
+ * `process.exit`. Soft-fail.
144
+ */
145
+ export async function flushSessionRunFatal(error: unknown): Promise<void> {
146
+ if (fatalFlush === undefined) {
147
+ return;
148
+ }
149
+ await Promise.race([
150
+ fatalFlush(error).catch(() => undefined),
151
+ new Promise<void>((resolve) => {
152
+ setTimeout(resolve, SESSION_RUN_FATAL_FLUSH_TIMEOUT_MS);
153
+ }),
154
+ ]);
155
+ }
156
+
157
+ function boundedText(value: string, max: number): string {
158
+ return value.length > max ? `${value.slice(0, max)}…` : value;
159
+ }
160
+
161
+ function boundedOptionalText(
162
+ value: string | undefined,
163
+ max: number
164
+ ): string | undefined {
165
+ if (value === undefined || value.length === 0) {
166
+ return undefined;
167
+ }
168
+ return boundedText(value, max);
169
+ }
170
+
171
+ export function serializeSessionRunError(error: unknown): SessionRunLogError {
172
+ if (error instanceof Error) {
173
+ const stack = boundedOptionalText(error.stack, MAX_ERROR_STACK_CHARS);
174
+ return {
175
+ name: boundedText(error.name.length > 0 ? error.name : "Error", 128),
176
+ message: boundedText(error.message, MAX_ERROR_MESSAGE_CHARS),
177
+ ...(stack === undefined ? {} : { stack }),
178
+ };
179
+ }
180
+ return {
181
+ name: "Error",
182
+ message: boundedText(String(error), MAX_ERROR_MESSAGE_CHARS),
183
+ };
184
+ }
185
+
186
+ export function snapshotSessionRunLogs(
187
+ entries: readonly LogRingEntry[]
188
+ ): LogRingEntry[] {
189
+ const tail = entries.slice(-SESSION_RUN_LOG_MAX_ENTRIES);
190
+ return tail.map((entry) => ({
191
+ index: entry.index,
192
+ at: entry.at,
193
+ line: boundedText(entry.line, SESSION_RUN_LOG_MAX_LINE_CHARS),
194
+ }));
195
+ }
196
+
197
+ function isRecord(value: unknown): value is Record<string, unknown> {
198
+ return typeof value === "object" && value !== null && !Array.isArray(value);
199
+ }
200
+
201
+ function decodeSinkBody(body: Uint8Array | { body: Uint8Array }): Uint8Array {
202
+ return body instanceof Uint8Array ? body : body.body;
203
+ }
204
+
205
+ function parseError(value: unknown): SessionRunLogError | undefined {
206
+ if (!isRecord(value)) {
207
+ return undefined;
208
+ }
209
+ const name = typeof value.name === "string" ? value.name : "";
210
+ const message = typeof value.message === "string" ? value.message : "";
211
+ const stack = typeof value.stack === "string" ? value.stack : undefined;
212
+ return {
213
+ name,
214
+ message,
215
+ ...(stack === undefined ? {} : { stack }),
216
+ };
217
+ }
218
+
219
+ function parseLogs(value: unknown): LogRingEntry[] {
220
+ if (!Array.isArray(value)) {
221
+ return [];
222
+ }
223
+ const logs: LogRingEntry[] = [];
224
+ for (const entry of value) {
225
+ if (!isRecord(entry)) {
226
+ continue;
227
+ }
228
+ if (
229
+ typeof entry.index !== "number" ||
230
+ typeof entry.at !== "string" ||
231
+ typeof entry.line !== "string"
232
+ ) {
233
+ continue;
234
+ }
235
+ logs.push({ index: entry.index, at: entry.at, line: entry.line });
236
+ }
237
+ return logs;
238
+ }
239
+
240
+ function parseExecution(value: unknown): SessionRunExecution | undefined {
241
+ if (!isRecord(value)) {
242
+ return undefined;
243
+ }
244
+ const executionId =
245
+ typeof value.executionId === "string" ? value.executionId : undefined;
246
+ const writtenAt =
247
+ typeof value.writtenAt === "string" ? value.writtenAt : undefined;
248
+ const sessionId =
249
+ typeof value.sessionId === "string" ? value.sessionId : undefined;
250
+ const turnStatus =
251
+ typeof value.turnStatus === "string" ? value.turnStatus : undefined;
252
+ const durationMs =
253
+ typeof value.durationMs === "number" && Number.isFinite(value.durationMs)
254
+ ? value.durationMs
255
+ : undefined;
256
+ if (
257
+ executionId === undefined ||
258
+ executionId.length === 0 ||
259
+ writtenAt === undefined ||
260
+ sessionId === undefined ||
261
+ turnStatus === undefined ||
262
+ turnStatus.length === 0 ||
263
+ durationMs === undefined ||
264
+ durationMs < 0
265
+ ) {
266
+ return undefined;
267
+ }
268
+ const abortReason =
269
+ typeof value.abortReason === "string" ? value.abortReason : undefined;
270
+ const message = typeof value.message === "string" ? value.message : undefined;
271
+ const error = parseError(value.error);
272
+ return {
273
+ executionId,
274
+ writtenAt,
275
+ sessionId,
276
+ turnStatus,
277
+ durationMs,
278
+ ...(abortReason === undefined
279
+ ? {}
280
+ : { abortReason: abortReason as SessionRunAbortReason }),
281
+ ...(message === undefined ? {} : { message }),
282
+ ...(error === undefined ? {} : { error }),
283
+ ...(value.processDeath === true ? { processDeath: true } : {}),
284
+ logs: parseLogs(value.logs),
285
+ };
286
+ }
287
+
288
+ export function lastFailureFromExecutions(
289
+ executions: readonly SessionRunExecution[]
290
+ ): SessionRunLastFailure | undefined {
291
+ const latest = executions.at(-1);
292
+ if (latest === undefined || latest.turnStatus === "finished") {
293
+ return undefined;
294
+ }
295
+ return {
296
+ executionId: latest.executionId,
297
+ writtenAt: latest.writtenAt,
298
+ turnStatus: latest.turnStatus,
299
+ ...(latest.abortReason === undefined
300
+ ? {}
301
+ : { abortReason: latest.abortReason }),
302
+ ...(latest.message === undefined ? {} : { message: latest.message }),
303
+ ...(latest.error === undefined ? {} : { error: latest.error }),
304
+ ...(latest.processDeath === true ? { processDeath: true } : {}),
305
+ };
306
+ }
307
+
308
+ function boundExecution(write: SessionRunExecution): SessionRunExecution {
309
+ const error =
310
+ write.error === undefined
311
+ ? undefined
312
+ : {
313
+ name: boundedText(write.error.name, 128),
314
+ message: boundedText(write.error.message, MAX_ERROR_MESSAGE_CHARS),
315
+ ...(write.error.stack === undefined
316
+ ? {}
317
+ : {
318
+ stack: boundedText(write.error.stack, MAX_ERROR_STACK_CHARS),
319
+ }),
320
+ };
321
+ return {
322
+ executionId: write.executionId,
323
+ writtenAt: write.writtenAt,
324
+ sessionId: write.sessionId,
325
+ turnStatus: write.turnStatus,
326
+ durationMs: write.durationMs,
327
+ ...(write.abortReason === undefined
328
+ ? {}
329
+ : { abortReason: write.abortReason }),
330
+ ...(boundedOptionalText(write.message, MAX_ERROR_MESSAGE_CHARS) ===
331
+ undefined
332
+ ? {}
333
+ : {
334
+ message: boundedOptionalText(write.message, MAX_ERROR_MESSAGE_CHARS),
335
+ }),
336
+ ...(error === undefined ? {} : { error }),
337
+ ...(write.processDeath === true ? { processDeath: true } : {}),
338
+ logs: snapshotSessionRunLogs(write.logs),
339
+ };
340
+ }
341
+
342
+ function upsertExecution(
343
+ existing: readonly SessionRunExecution[],
344
+ next: SessionRunExecution
345
+ ): SessionRunExecution[] {
346
+ const executions = existing.filter(
347
+ (entry) => entry.executionId !== next.executionId
348
+ );
349
+ executions.push(next);
350
+ executions.sort((a, b) => a.writtenAt.localeCompare(b.writtenAt));
351
+ return executions.slice(-SESSION_RUN_LOG_MAX_EXECUTIONS);
352
+ }
353
+
354
+ function shrinkSessionDocument(
355
+ document: SessionRunLogDocument
356
+ ): SessionRunLogDocument {
357
+ let executions = document.executions;
358
+ let next: SessionRunLogDocument = {
359
+ ...document,
360
+ executions,
361
+ lastFailure: lastFailureFromExecutions(executions),
362
+ };
363
+ let serialized = JSON.stringify(next);
364
+ while (serialized.length > MAX_DOCUMENT_CHARS) {
365
+ const oldestWithLogs = executions.findIndex(
366
+ (entry) => entry.logs.length > 0
367
+ );
368
+ if (oldestWithLogs >= 0) {
369
+ const entry = executions[oldestWithLogs]!;
370
+ executions = executions.map((item, index) =>
371
+ index === oldestWithLogs
372
+ ? {
373
+ ...entry,
374
+ logs: entry.logs.slice(Math.ceil(entry.logs.length / 2)),
375
+ }
376
+ : item
377
+ );
378
+ } else if (executions.length > 1) {
379
+ executions = executions.slice(1);
380
+ } else {
381
+ break;
382
+ }
383
+ next = {
384
+ ...document,
385
+ executions,
386
+ lastFailure: lastFailureFromExecutions(executions),
387
+ };
388
+ serialized = JSON.stringify(next);
389
+ }
390
+ return next;
391
+ }
392
+
393
+ export function parseSessionRunLogDocument(
394
+ value: unknown
395
+ ): SessionRunLogDocument | undefined {
396
+ if (!isRecord(value) || value.v !== SESSION_RUN_LOG_VERSION) {
397
+ return undefined;
398
+ }
399
+ const sessionPublicId =
400
+ typeof value.sessionPublicId === "string"
401
+ ? value.sessionPublicId
402
+ : undefined;
403
+ const updatedAt =
404
+ typeof value.updatedAt === "string" ? value.updatedAt : undefined;
405
+ if (
406
+ sessionPublicId === undefined ||
407
+ sessionPublicId.length === 0 ||
408
+ updatedAt === undefined ||
409
+ !Array.isArray(value.executions)
410
+ ) {
411
+ return undefined;
412
+ }
413
+ const executions: SessionRunExecution[] = [];
414
+ for (const entry of value.executions) {
415
+ const parsed = parseExecution(entry);
416
+ if (parsed !== undefined) {
417
+ executions.push(parsed);
418
+ }
419
+ }
420
+ executions.sort((a, b) => a.writtenAt.localeCompare(b.writtenAt));
421
+ const lastFailure = lastFailureFromExecutions(executions);
422
+ return {
423
+ v: SESSION_RUN_LOG_VERSION,
424
+ sessionPublicId,
425
+ updatedAt,
426
+ ...(lastFailure === undefined ? {} : { lastFailure }),
427
+ executions,
428
+ };
429
+ }
430
+
431
+ export function createSessionRunLogStore(input: {
432
+ sink: FileSink;
433
+ agentName: string;
434
+ logger?: (line: string) => void;
435
+ snapshotLogs?: () => readonly LogRingEntry[];
436
+ }): SessionRunLogStore {
437
+ const { sink, agentName } = input;
438
+ const logger = input.logger ?? (() => {});
439
+ let active: ActiveExecution | undefined;
440
+
441
+ const readDocument = async (
442
+ sessionPublicId: string
443
+ ): Promise<SessionRunLogDocument | undefined> => {
444
+ const key = storageKeys.sessionRun(agentName, sessionPublicId);
445
+ const body = await sink.get(key);
446
+ if (body === undefined) {
447
+ return undefined;
448
+ }
449
+ try {
450
+ return parseSessionRunLogDocument(
451
+ JSON.parse(new TextDecoder().decode(decodeSinkBody(body)))
452
+ );
453
+ } catch (error) {
454
+ logger(
455
+ `[agent-sdk] session-run log: skip unreadable ${key} (${describeError(error)})`
456
+ );
457
+ return undefined;
458
+ }
459
+ };
460
+
461
+ const persistWrite = async (
462
+ write: SessionRunExecutionWrite
463
+ ): Promise<void> => {
464
+ const fitted = boundExecution(write);
465
+ let existing: SessionRunLogDocument | undefined;
466
+ try {
467
+ existing = await readDocument(write.sessionPublicId);
468
+ } catch (error) {
469
+ logger(
470
+ `[agent-sdk] session-run log: persist failed for ${fitted.executionId} (${describeError(error)})`
471
+ );
472
+ return;
473
+ }
474
+ const executions = upsertExecution(existing?.executions ?? [], fitted);
475
+ const document = shrinkSessionDocument({
476
+ v: SESSION_RUN_LOG_VERSION,
477
+ sessionPublicId: write.sessionPublicId,
478
+ updatedAt: fitted.writtenAt,
479
+ executions,
480
+ });
481
+ const key = storageKeys.sessionRun(agentName, document.sessionPublicId);
482
+ try {
483
+ await sink.put(key, new TextEncoder().encode(JSON.stringify(document)));
484
+ } catch (error) {
485
+ logger(
486
+ `[agent-sdk] session-run log: persist failed for ${fitted.executionId} (${describeError(error)})`
487
+ );
488
+ return;
489
+ }
490
+ if (fitted.turnStatus === "running") {
491
+ active = {
492
+ sessionPublicId: write.sessionPublicId,
493
+ executionId: fitted.executionId,
494
+ sessionId: fitted.sessionId,
495
+ startedAt: Date.now(),
496
+ };
497
+ return;
498
+ }
499
+ if (active?.executionId === fitted.executionId) {
500
+ active = undefined;
501
+ }
502
+ };
503
+
504
+ return {
505
+ persist: persistWrite,
506
+
507
+ async read(sessionPublicId) {
508
+ try {
509
+ return await readDocument(sessionPublicId);
510
+ } catch (error) {
511
+ logger(
512
+ `[agent-sdk] session-run log: read failed for ${sessionPublicId} (${describeError(error)})`
513
+ );
514
+ return undefined;
515
+ }
516
+ },
517
+
518
+ async flushProcessDeath(reason, error) {
519
+ if (active === undefined) {
520
+ return;
521
+ }
522
+ const current = active;
523
+ const serialized =
524
+ error === undefined ? undefined : serializeSessionRunError(error);
525
+ const message =
526
+ error instanceof Error
527
+ ? error.message
528
+ : error !== undefined
529
+ ? String(error)
530
+ : "process died during hosted execution";
531
+ await persistWrite({
532
+ sessionPublicId: current.sessionPublicId,
533
+ executionId: current.executionId,
534
+ writtenAt: new Date().toISOString(),
535
+ sessionId: current.sessionId,
536
+ turnStatus: "error",
537
+ durationMs: Math.max(0, Date.now() - current.startedAt),
538
+ abortReason: reason,
539
+ processDeath: true,
540
+ message,
541
+ ...(serialized === undefined ? {} : { error: serialized }),
542
+ logs: snapshotSessionRunLogs(input.snapshotLogs?.() ?? []),
543
+ });
544
+ },
545
+ };
546
+ }
547
+
548
+ /**
549
+ * Same selection as the conversation mirror: architecture-v2 hosted
550
+ * engines with a provisioned framework file store. Self-hosted and v1
551
+ * stay on local disk / today's behavior. This is the only path that
552
+ * installs the session-run log — v1 never writes these documents.
553
+ */
554
+ export function selectSessionRunLogStore(input: {
555
+ project: AgentProject;
556
+ logger?: (line: string) => void;
557
+ env?: Record<string, string | undefined>;
558
+ snapshotLogs?: () => readonly LogRingEntry[];
559
+ }): SessionRunLogStore | undefined {
560
+ if (input.project.agent.architecture !== "v2") {
561
+ return undefined;
562
+ }
563
+ const env = input.env ?? process.env;
564
+ const frameworkStoreId = cursorFrameworkStoreSourceId(
565
+ env as NodeJS.ProcessEnv
566
+ );
567
+ if (
568
+ env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined ||
569
+ frameworkStoreId === undefined
570
+ ) {
571
+ return undefined;
572
+ }
573
+ return createSessionRunLogStore({
574
+ sink: cursorHostedFiles({
575
+ storeSourceId: frameworkStoreId,
576
+ resolveApiKey: () => resolveApiKeySync()?.apiKey,
577
+ }),
578
+ agentName: input.project.name,
579
+ logger: input.logger,
580
+ ...(input.snapshotLogs === undefined
581
+ ? {}
582
+ : { snapshotLogs: input.snapshotLogs }),
583
+ });
584
+ }
@@ -18,24 +18,32 @@ export interface ListedSessions {
18
18
  source?: SessionListSource;
19
19
  }
20
20
 
21
- export async function listSessions(args: {
21
+ export interface ListSessionsArgs {
22
22
  baseUrl: string;
23
23
  auth?: RequestAuth;
24
24
  fetchImpl?: typeof fetch;
25
- }): Promise<SessionSummary[]> {
25
+ /**
26
+ * Ask for only the newest visible session (`?latest=1`). The server
27
+ * answers from memory where it can instead of scanning durable storage.
28
+ */
29
+ latest?: boolean;
30
+ }
31
+
32
+ export async function listSessions(
33
+ args: ListSessionsArgs
34
+ ): Promise<SessionSummary[]> {
26
35
  return (await listSessionsWithSource(args)).sessions;
27
36
  }
28
37
 
29
- export async function listSessionsWithSource(args: {
30
- baseUrl: string;
31
- auth?: RequestAuth;
32
- fetchImpl?: typeof fetch;
33
- }): Promise<ListedSessions> {
38
+ export async function listSessionsWithSource(
39
+ args: ListSessionsArgs
40
+ ): Promise<ListedSessions> {
34
41
  const baseUrl = args.baseUrl.replace(/\/$/, "");
35
42
  const fetchImpl = args.fetchImpl ?? fetch;
43
+ const query = args.latest === true ? "?latest=1" : "";
36
44
  let resp: Response;
37
45
  try {
38
- resp = await fetchImpl(`${baseUrl}/v1/sessions`, {
46
+ resp = await fetchImpl(`${baseUrl}/v1/sessions${query}`, {
39
47
  headers: mergeRequestHeaders(args.auth),
40
48
  });
41
49
  } catch (error) {
@@ -168,6 +176,7 @@ function parseSessionSummary(value: unknown): SessionSummary | undefined {
168
176
  queued: typeof row.queued === "boolean" ? row.queued : undefined,
169
177
  createdAt: typeof row.createdAt === "string" ? row.createdAt : "",
170
178
  updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : "",
179
+ dryRun: row.dryRun === true ? true : undefined,
171
180
  continuationToken,
172
181
  externalUrl:
173
182
  typeof row.externalUrl === "string" ? row.externalUrl : undefined,