@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
@@ -30,6 +30,7 @@ import {
30
30
  resolveStoragePolicy,
31
31
  type StorageContext,
32
32
  type StorageDefinition,
33
+ type StorageEntry,
33
34
  storageKeys,
34
35
  } from "../storage.js";
35
36
  import { isCursorHostedStorage } from "../storage-backends/cursor-hosted.js";
@@ -37,6 +38,7 @@ import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
37
38
  import type { ABSnapshot } from "./ab-snapshot.js";
38
39
  import { describeError } from "./describe-error.js";
39
40
  import type { EvalRunStorage } from "./eval-run-store.js";
41
+ import { isAuthorKvUnsupported } from "./null-kv-storage.js";
40
42
  import type {
41
43
  AuthorKvStore,
42
44
  EvalAbStore,
@@ -97,6 +99,18 @@ interface SessionBuffer {
97
99
  debounceTimer?: ReturnType<typeof setTimeout>;
98
100
  }
99
101
 
102
+ /** Session records out of raw sink entries; rows without a usable id are dropped. */
103
+ function sessionRecordsOf(entries: readonly StorageEntry[]): SessionRecord[] {
104
+ return entries
105
+ .map((entry) => entry.value as unknown as SessionRecord)
106
+ .filter(
107
+ (record) =>
108
+ record != null &&
109
+ typeof record.sessionId === "string" &&
110
+ record.sessionId !== ""
111
+ );
112
+ }
113
+
100
114
  export class StorageCoordinator
101
115
  implements FrameworkSessionStore, AuthorKvStore, EvalAbStore
102
116
  {
@@ -315,14 +329,31 @@ export class StorageCoordinator
315
329
  if (!Array.isArray(entries)) {
316
330
  throw new Error("storage list returned a non-array");
317
331
  }
318
- return entries
319
- .map((entry) => entry.value as unknown as SessionRecord)
320
- .filter(
321
- (record) =>
322
- record != null &&
323
- typeof record.sessionId === "string" &&
324
- record.sessionId !== ""
325
- );
332
+ return sessionRecordsOf(entries);
333
+ }
334
+
335
+ /**
336
+ * Newest-written session records from the sink (`GET /v1/sessions?latest=1`
337
+ * on a host whose local store has nothing for the caller). Same error
338
+ * posture as {@link listSessionsFromSink}; `undefined` when the sink
339
+ * cannot order by write time, so the caller falls back to the full list.
340
+ */
341
+ async listNewestSessionsFromSink(
342
+ limit: number
343
+ ): Promise<SessionRecord[] | undefined> {
344
+ const listNewest = this.definition.listNewest;
345
+ if (listNewest === undefined) {
346
+ return undefined;
347
+ }
348
+ const entries = await listNewest(
349
+ storageKeys.sessionPrefix(this.agentName),
350
+ limit,
351
+ this.context("restore")
352
+ );
353
+ if (!Array.isArray(entries)) {
354
+ throw new Error("storage listNewest returned a non-array");
355
+ }
356
+ return sessionRecordsOf(entries);
326
357
  }
327
358
 
328
359
  /**
@@ -438,9 +469,18 @@ export class StorageCoordinator
438
469
  /**
439
470
  * Whether the sink can serve awaited author reads/writes (`get` is
440
471
  * required — `put` is always present on {@link StorageConfig}).
472
+ *
473
+ * A sink may keep `get` for framework session state while refusing author
474
+ * KV: hosted v2 reads sessions from the framework file store but has no
475
+ * working KV backend, and author handlers that cannot read their own
476
+ * writes back are better served by the local-disk fallback than by a sink
477
+ * that accepts every write and forgets it.
441
478
  */
442
479
  get supportsAuthorKv(): boolean {
443
- return this.definition.get !== undefined;
480
+ return (
481
+ this.definition.get !== undefined &&
482
+ !isAuthorKvUnsupported(this.definition)
483
+ );
444
484
  }
445
485
 
446
486
  /**
@@ -54,6 +54,13 @@ export interface FrameworkSessionStore {
54
54
 
55
55
  listSessions(): Promise<SessionRecord[]>;
56
56
  listSessionsFromSink(): Promise<SessionRecord[]>;
57
+ /**
58
+ * The `limit` most recently written session records from the sink,
59
+ * newest first; `undefined` when the sink has no `listNewest`.
60
+ */
61
+ listNewestSessionsFromSink(
62
+ limit: number
63
+ ): Promise<SessionRecord[] | undefined>;
57
64
  listSessionEvents(sessionId: string): Promise<SessionEvent[]>;
58
65
  getSessionById(sessionId: string): Promise<SessionRecord | undefined>;
59
66
  getSessionByContinuation(
@@ -154,6 +154,25 @@ export function createStreamProgress(options?: {
154
154
  );
155
155
  break;
156
156
  }
157
+ case "action.auth_requested": {
158
+ closeAssistant();
159
+ write(
160
+ ` ${c.yellow("⏸")} ${c.bold(event.data.connection)} ${c.dim(
161
+ "awaiting MCP authorization"
162
+ )}\n`
163
+ );
164
+ break;
165
+ }
166
+ case "action.auth_resolved": {
167
+ const mark =
168
+ event.data.decision === "approve" ? c.green("✓") : c.red("✗");
169
+ write(
170
+ ` ${mark} ${c.bold(event.data.connection)} ${c.dim(
171
+ event.data.decision === "approve" ? "connected" : "denied"
172
+ )}\n`
173
+ );
174
+ break;
175
+ }
157
176
  case "action.result": {
158
177
  if (
159
178
  event.data.toolName === "task" &&
@@ -10,11 +10,13 @@
10
10
  */
11
11
 
12
12
  import type {
13
+ DiscoveredTool,
13
14
  McpToolAnnotations,
14
15
  ToolEffect,
15
16
  ToolEffectDeclaration,
16
17
  ToolExecuteResult,
17
18
  } from "../types.js";
19
+ import { timeArgViolation } from "./as-of.js";
18
20
 
19
21
  /** What the host does with one tool call. */
20
22
  export type ToolDecision =
@@ -23,12 +25,17 @@ export type ToolDecision =
23
25
  /** Do not run it; return this to the model instead. */
24
26
  | { kind: "answer"; result: ToolExecuteResult }
25
27
  /**
26
- * Do not run it; fail the call with this message. Only ever produced in a
27
- * dry run, for an MCP tool nothing classifies: stubbing it would let the
28
- * run reach a confident conclusion from no data, and running it could leak
29
- * a real write — refusing is the one failure that is loud.
28
+ * Do not run it; fail the call with this message. Only produced in a dry
29
+ * run, for an MCP tool nothing classifies: stubbing it would let the run
30
+ * reach a confident conclusion from no data, and running it could leak a
31
+ * real write — refusing is the one failure that is loud.
30
32
  */
31
- | { kind: "refuse"; message: string };
33
+ | { kind: "refuse"; message: string }
34
+ /**
35
+ * Do not run it; the `asOf` session was asked to read without absolute
36
+ * bounds, which would read the present.
37
+ */
38
+ | { kind: "unbounded"; message: string };
32
39
 
33
40
  /** What a policy decision needs to know about the call. */
34
41
  export interface ToolCallFacts {
@@ -47,12 +54,16 @@ export interface ToolCallFacts {
47
54
  /** What a stubbed write should answer with, if the tool supplied one. */
48
55
  dryRunResult?: ToolExecuteResult | ((input: never) => ToolExecuteResult);
49
56
  /**
50
- * Validated input, as the tool body would receive it. Only read by a
51
- * per-call `effect` predicate and by a `dryRunResult` function, so a caller
52
- * with neither — a bridged MCP tool, which carries no declaration at all —
53
- * can omit it.
57
+ * Validated input, as the tool body would receive it. Read by a per-call
58
+ * `effect` predicate, a `dryRunResult` function, and the {@link timeArgs}
59
+ * bound check, so a caller with none of those — a bridged MCP tool, which
60
+ * carries no declaration at all — can omit it.
54
61
  */
55
62
  input?: unknown;
63
+ /** The session's frozen instant, when it has one. */
64
+ asOf?: string;
65
+ /** The tool's declared time-bound argument names, if it made them. */
66
+ timeArgs?: readonly string[];
56
67
  }
57
68
 
58
69
  /**
@@ -111,6 +122,23 @@ export function classifyAnnotationsEffect(
111
122
  return undefined;
112
123
  }
113
124
 
125
+ /**
126
+ * The effect of one direct call on a discovered tool, the same way
127
+ * {@link decideToolCall} reads it: the authored declaration when there is
128
+ * one (possibly per input), else the MCP server's own annotations for an
129
+ * advertised passthrough. `undefined` is an advertised tool nothing
130
+ * classifies; callers gating on "read" treat it as a write.
131
+ */
132
+ export function directCallEffect(
133
+ tool: Pick<DiscoveredTool, "advertised" | "annotations" | "definition">,
134
+ input: unknown
135
+ ): ToolEffect | undefined {
136
+ if (tool.definition.effect === undefined && tool.advertised === true) {
137
+ return classifyAnnotationsEffect(tool.annotations);
138
+ }
139
+ return resolveEffect(tool.definition.effect, input);
140
+ }
141
+
114
142
  /**
115
143
  * What a dry run answers when nothing classifies an MCP tool. Deliberately
116
144
  * reads as a strict API rather than disclosing the session's posture (see
@@ -129,6 +157,18 @@ function unclassifiedRefusal(toolName: string): string {
129
157
 
130
158
  /** Decide what to do with one tool call. Pure; no I/O, no session state. */
131
159
  export function decideToolCall(facts: ToolCallFacts): ToolDecision {
160
+ // Before the dry-run split: a frozen session bounds its reads whether or
161
+ // not its writes are stubbed.
162
+ if (
163
+ facts.asOf !== undefined &&
164
+ facts.timeArgs !== undefined &&
165
+ facts.timeArgs.length > 0
166
+ ) {
167
+ const violation = timeArgViolation(facts.input, facts.timeArgs, facts.asOf);
168
+ if (violation !== undefined) {
169
+ return { kind: "unbounded", message: violation };
170
+ }
171
+ }
132
172
  if (!facts.dryRun) {
133
173
  return { kind: "run" };
134
174
  }
@@ -170,6 +170,16 @@ export function buildTrajectory(events: SessionEvent[]): Trajectory {
170
170
  }
171
171
  break;
172
172
  }
173
+ case "action.auth_requested": {
174
+ break;
175
+ }
176
+ case "action.auth_resolved": {
177
+ const pending = pendingCalls.get(event.data.callId);
178
+ if (pending !== undefined) {
179
+ pending.approvalDecision = event.data.decision;
180
+ }
181
+ break;
182
+ }
173
183
  case "action.result": {
174
184
  const pending = pendingCalls.get(event.data.callId);
175
185
  if (pending !== undefined) {
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Hand-off of a message to the server that holds the session's turn lease.
3
+ *
4
+ * Blue/green replicas share a state root but not a process, and only the
5
+ * lease holder can admit a message to its running turn. A server that
6
+ * receives a message for a turn it does not own drops it here, under
7
+ * `<stateRoot>/outbox/<sessionId>`; the holder takes everything out while its
8
+ * turn runs and once more after releasing the lease. Local messages never
9
+ * touch this.
10
+ */
11
+
12
+ import { randomUUID } from "node:crypto";
13
+ import {
14
+ mkdir,
15
+ readdir,
16
+ readFile,
17
+ rename,
18
+ rm,
19
+ unlink,
20
+ writeFile,
21
+ } from "node:fs/promises";
22
+ import { join } from "node:path";
23
+
24
+ export interface OutboxItem<T> {
25
+ message: string;
26
+ options: T;
27
+ }
28
+
29
+ function safeKey(sessionId: string): string {
30
+ const sanitized = sessionId
31
+ .trim()
32
+ .replace(/[^a-zA-Z0-9._-]+/g, "_")
33
+ .replace(/^\.+/, "")
34
+ .replace(/\.+/g, "_")
35
+ .slice(0, 180);
36
+ return sanitized === "" ? "_empty" : sanitized;
37
+ }
38
+
39
+ export class TurnOutbox<T> {
40
+ private readonly rootDir: string;
41
+
42
+ constructor(rootDir: string) {
43
+ this.rootDir = rootDir;
44
+ }
45
+
46
+ private dir(sessionId: string): string {
47
+ return join(this.rootDir, safeKey(sessionId));
48
+ }
49
+
50
+ async post(sessionId: string, item: OutboxItem<T>): Promise<void> {
51
+ const dir = this.dir(sessionId);
52
+ await mkdir(dir, { recursive: true });
53
+ // Timestamp first so a listing sorts in arrival order.
54
+ const path = join(dir, `${Date.now()}-${randomUUID()}.json`);
55
+ await writeFile(`${path}.tmp`, `${JSON.stringify(item)}\n`, "utf8");
56
+ await rename(`${path}.tmp`, path);
57
+ }
58
+
59
+ /** Remove and return everything posted, in arrival order. */
60
+ async takeAll(sessionId: string): Promise<OutboxItem<T>[]> {
61
+ const dir = this.dir(sessionId);
62
+ let names: string[];
63
+ try {
64
+ names = await readdir(dir);
65
+ } catch {
66
+ return [];
67
+ }
68
+ const items: OutboxItem<T>[] = [];
69
+ for (const name of names.filter((n) => n.endsWith(".json")).sort()) {
70
+ const path = join(dir, name);
71
+ try {
72
+ const raw = await readFile(path, "utf8");
73
+ await unlink(path);
74
+ items.push(JSON.parse(raw) as OutboxItem<T>);
75
+ } catch {
76
+ // Taken by the holder between readdir and here.
77
+ }
78
+ }
79
+ return items;
80
+ }
81
+
82
+ async clear(sessionId: string): Promise<void> {
83
+ await rm(this.dir(sessionId), { recursive: true, force: true });
84
+ }
85
+ }
@@ -108,7 +108,7 @@ export function isCursorHostedStorage(value: unknown): boolean {
108
108
  }
109
109
 
110
110
  type CursorHostedStorageMethods = Required<
111
- Pick<StorageConfig, "put" | "get" | "delete" | "list">
111
+ Pick<StorageConfig, "put" | "get" | "delete" | "list" | "listNewest">
112
112
  > & {
113
113
  readonly [CURSOR_HOSTED_STORAGE]: true;
114
114
  cas: StorageCasTable;
@@ -284,6 +284,18 @@ export function cursorHostedStorage(
284
284
  }>(options, "/internal/agent-serve/storage/kv/list", { prefix });
285
285
  return result.entries;
286
286
  },
287
+ async listNewest(prefix, limit): Promise<StorageEntry[]> {
288
+ // Same route; the server orders the prefix range by row write time
289
+ // and caps the rows instead of returning the whole range.
290
+ const result = await storageRpc<{
291
+ entries: Array<{ key: string; value: JsonValue }>;
292
+ }>(options, "/internal/agent-serve/storage/kv/list", {
293
+ prefix,
294
+ limit,
295
+ newestFirst: true,
296
+ });
297
+ return result.entries;
298
+ },
287
299
  // Conditional writes over the same proxy (server routes: see the CAS
288
300
  // wire-protocol block above). The proxy scopes rows from the service
289
301
  // account, so ctx is not part of the wire contract.
@@ -38,6 +38,7 @@ const DURABLE_SESSION_RECORD_KEY_RE =
38
38
  * | --- | --- |
39
39
  * | `agentkit/v1/{agent}/session/{sessionId}` | `SessionRecord` |
40
40
  * | `agentkit/v1/{agent}/session-events/{sessionId}/{index}` | `SessionEvent[]` chunk (index = first event's index, zero-padded) |
41
+ * | `agentkit/v1/{agent}/session-runs/{sessionPublicId}` | One session-level hosted-execution log (executions[] + lastFailure) |
41
42
  * | `agentkit/v1/{agent}/continuation/{channelId}/{token}` | `{ sessionId }` |
42
43
  * | `agentkit/v1/{agent}/kv/{key}` | Author JSON via `HostContext.kv` |
43
44
  *
@@ -59,6 +60,15 @@ export const storageKeys = {
59
60
  `${STORAGE_KEY_ROOT}/${agent}/session-events/${sessionId}/${String(firstIndex).padStart(8, "0")}`,
60
61
  sessionEventsPrefix: (agent: string, sessionId: string): string =>
61
62
  `${STORAGE_KEY_ROOT}/${agent}/session-events/${sessionId}/`,
63
+ /**
64
+ * One session-level hosted-execution log (v2 only). `sessionPublicId` is
65
+ * the factory `ses_…` so a throw that never minted a July session still
66
+ * lands under a stable key. Per-execution rows live inside the document.
67
+ */
68
+ sessionRun: (agent: string, sessionPublicId: string): string =>
69
+ `${STORAGE_KEY_ROOT}/${agent}/session-runs/${keySegment(sessionPublicId)}`,
70
+ sessionRunsPrefix: (agent: string): string =>
71
+ `${STORAGE_KEY_ROOT}/${agent}/session-runs/`,
62
72
  continuation: (
63
73
  agent: string,
64
74
  channelId: string,
package/src/storage.ts CHANGED
@@ -275,6 +275,18 @@ export interface StorageConfig {
275
275
  prefix: string,
276
276
  ctx: StorageContext
277
277
  ): StorageEntry[] | Promise<StorageEntry[]>;
278
+ /**
279
+ * The `limit` most recently **written** entries under a prefix, newest
280
+ * first. Optional — a backend-native shortcut for `GET /v1/sessions?latest=1`
281
+ * on a replacement host, where the alternative is listing every session
282
+ * row. Without it the engine falls back to `list`. Write order is an
283
+ * approximation of the records' own `updatedAt`; callers tolerate that.
284
+ */
285
+ listNewest?(
286
+ prefix: string,
287
+ limit: number,
288
+ ctx: StorageContext
289
+ ): StorageEntry[] | Promise<StorageEntry[]>;
278
290
  }
279
291
 
280
292
  export type StorageDefinition = StorageConfig & {
package/src/tools.ts CHANGED
@@ -99,6 +99,15 @@ type ServerToolConfig<TSchema> = {
99
99
  * write, so a dry-run session answers it instead of running it.
100
100
  */
101
101
  effect?: ToolEffectDeclaration<ToolInput<TSchema>>;
102
+ /**
103
+ * Input properties carrying time bounds. In an `asOf` session each named
104
+ * argument must be an absolute ISO-8601 instant with a timezone, no later
105
+ * than the frozen instant; a call that omits one, or supplies a relative
106
+ * or later value, is refused so the model retries with absolute bounds.
107
+ * Names must exist in {@link inputSchema} or the frozen session refuses to
108
+ * start. Ignored without `asOf`.
109
+ */
110
+ timeArgs?: readonly string[];
102
111
  /** What a `"write"` tool returns in a dry-run session. */
103
112
  dryRunResult?:
104
113
  | ToolExecuteResult
@@ -126,10 +135,11 @@ type AgentToolConfig<TSchema> = {
126
135
  needsApproval?: never;
127
136
  /**
128
137
  * Agent tools run inside the harness, not through the host's tool path, so
129
- * a dry run cannot answer them. Classify the work as a server tool if it
130
- * needs to be dry-runnable.
138
+ * a dry run cannot answer them and an `asOf` session cannot bound them.
139
+ * Classify the work as a server tool if it needs either.
131
140
  */
132
141
  effect?: never;
142
+ timeArgs?: never;
133
143
  dryRunResult?: never;
134
144
  };
135
145
 
package/src/types.ts CHANGED
@@ -316,7 +316,8 @@ export interface AgentConcurrencyOptions {
316
316
  * {@link MAX_RUNNING_TURNS_LIMIT}. Omit for unlimited.
317
317
  *
318
318
  * A queued turn still counts as `running` for busy semantics
319
- * (follow-ups preempt it; direct tool calls get `SessionBusyError`),
319
+ * (follow-ups preempt it; direct write-effect tool calls get
320
+ * `SessionBusyError`),
320
321
  * and a follow-up that preempts a queued turn re-queues at the back.
321
322
  */
322
323
  maxRunningTurns?: number;
@@ -879,6 +880,8 @@ export interface ToolContext {
879
880
  * `subagent.completed`). Omitted for scratch `callTool` with no session.
880
881
  */
881
882
  emit?: (payload: SessionEventPayload) => void;
883
+ /** The session's frozen `asOf`, or the wall clock. Use instead of `Date.now()`. */
884
+ now(): Date;
882
885
  }
883
886
 
884
887
  /**
@@ -991,6 +994,17 @@ export interface ToolConfig<TInput> {
991
994
  * write, so a dry run stubs it — see {@link ToolEffect}.
992
995
  */
993
996
  effect?: ToolEffectDeclaration<TInput>;
997
+ /**
998
+ * Input properties that carry time bounds. In a session created with
999
+ * {@link SendMessageOptions.asOf}, every named argument must be an
1000
+ * absolute ISO-8601 instant with a timezone, no later than the session's
1001
+ * frozen instant — a call that omits one, or supplies a relative or later
1002
+ * value, is refused so the model retries with absolute bounds. Names must
1003
+ * exist in {@link inputSchema}; a session with `asOf` refuses to start
1004
+ * otherwise, because a misspelled name would silently check nothing.
1005
+ * Ignored in sessions without `asOf`.
1006
+ */
1007
+ timeArgs?: readonly string[];
994
1008
  /**
995
1009
  * What a write tool returns in a dry-run session instead of executing.
996
1010
  *
@@ -1024,6 +1038,7 @@ export interface ToolDefinition extends BrandedDefinition<"tool"> {
1024
1038
  readonly outputSchema?: z.ZodTypeAny | JsonSchemaObject;
1025
1039
  readonly needsApproval?: ToolNeedsApproval<never>;
1026
1040
  readonly effect?: ToolEffectDeclaration<never>;
1041
+ readonly timeArgs?: readonly string[];
1027
1042
  readonly dryRunResult?:
1028
1043
  | ToolExecuteResult
1029
1044
  | ((input: never) => ToolExecuteResult);
@@ -1151,7 +1166,9 @@ export function cursorAccountServersHasMixedWildcard(
1151
1166
  */
1152
1167
  export function isHostOauthConnectionTransport(
1153
1168
  transport: ConnectionTransport
1154
- ): boolean {
1169
+ ): transport is Extract<ConnectionTransport, { url: string }> & {
1170
+ oauth: true;
1171
+ } {
1155
1172
  return "url" in transport && transport.oauth === true;
1156
1173
  }
1157
1174
 
@@ -1380,8 +1397,18 @@ export interface PendingApproval {
1380
1397
  requestedAt: string;
1381
1398
  }
1382
1399
 
1400
+ /** Durable record of a tool call waiting on MCP authorization. */
1401
+ export interface PendingAuth {
1402
+ callId: string;
1403
+ turnId: string;
1404
+ toolName: string;
1405
+ connection: string;
1406
+ authUrl: string;
1407
+ requestedAt: string;
1408
+ }
1409
+
1383
1410
  export type SessionEventPayload =
1384
- | { type: "session.started"; data: { channelId: string } }
1411
+ | { type: "session.started"; data: { channelId: string; dryRun?: boolean } }
1385
1412
  | {
1386
1413
  /**
1387
1414
  * Sticky A/B enrollment for one experiment (`defineAB` under `agent/ab`).
@@ -1457,6 +1484,31 @@ export type SessionEventPayload =
1457
1484
  parentCallId?: string;
1458
1485
  };
1459
1486
  }
1487
+ | {
1488
+ /**
1489
+ * A host MCP call/list needs OAuth. The turn stays running until
1490
+ * the human completes the `authUrl` and the runtime retries.
1491
+ */
1492
+ type: "action.auth_requested";
1493
+ data: {
1494
+ callId: string;
1495
+ toolName: string;
1496
+ connection: string;
1497
+ authUrl: string;
1498
+ parentCallId?: string;
1499
+ };
1500
+ }
1501
+ | {
1502
+ type: "action.auth_resolved";
1503
+ data: {
1504
+ callId: string;
1505
+ toolName: string;
1506
+ connection: string;
1507
+ decision: ApprovalDecision;
1508
+ by?: string;
1509
+ parentCallId?: string;
1510
+ };
1511
+ }
1460
1512
  | {
1461
1513
  type: "action.result";
1462
1514
  data: {
@@ -1586,6 +1638,8 @@ export interface SessionInfo {
1586
1638
  purpose?: SessionPurpose;
1587
1639
  /** True when write-classified tool calls are answered by the host. */
1588
1640
  dryRun?: boolean;
1641
+ /** Frozen instant this session reads at; absent means the wall clock. */
1642
+ asOf?: string;
1589
1643
  auth: AuthContext | null;
1590
1644
  title?: string;
1591
1645
  /**
@@ -1620,6 +1674,8 @@ export interface SessionRecord {
1620
1674
  purpose?: SessionPurpose;
1621
1675
  /** Frozen at create from {@link SendMessageOptions.dryRun}. */
1622
1676
  dryRun?: boolean;
1677
+ /** Frozen at create from {@link SendMessageOptions.asOf}. */
1678
+ asOf?: string;
1623
1679
  /**
1624
1680
  * Denormalized sticky A/B arms (mirrors durable `ab.assigned` events) so
1625
1681
  * the agent loop / tools can read arms without re-folding the log. Source
@@ -1672,6 +1728,11 @@ export interface SessionRecord {
1672
1728
  * SDK tool callback cannot be resumed after process restart).
1673
1729
  */
1674
1730
  pendingApprovals?: PendingApproval[];
1731
+ /**
1732
+ * Server-tool MCP calls parked for host or Cursor-account OAuth.
1733
+ * Cleared when resolved or when the host restarts without a live waiter.
1734
+ */
1735
+ pendingAuths?: PendingAuth[];
1675
1736
  turnCount: number;
1676
1737
  createdAt: string;
1677
1738
  updatedAt: string;
@@ -1708,6 +1769,8 @@ export interface SessionSummary {
1708
1769
  queued?: boolean;
1709
1770
  createdAt: string;
1710
1771
  updatedAt: string;
1772
+ /** True when write-classified tool calls are answered by the host. */
1773
+ dryRun?: boolean;
1711
1774
  /** Active wire token for HTTP follow-ups, or null when not addressable. */
1712
1775
  continuationToken: string | null;
1713
1776
  /**
@@ -1808,6 +1871,13 @@ export interface SendMessageOptions {
1808
1871
  * model chose stay on the session log as the record of the intended action.
1809
1872
  */
1810
1873
  dryRun?: boolean;
1874
+ /**
1875
+ * ISO-8601 instant with a timezone, frozen at create: the prompt states
1876
+ * it, {@link ToolContext.now} returns it, and tools that declare
1877
+ * {@link ToolConfig.timeArgs} refuse calls not bounded at or before it. A
1878
+ * tool that declares nothing still reads the present.
1879
+ */
1880
+ asOf?: string;
1811
1881
  /**
1812
1882
  * Absolute directory used as the local harness `cwd` for this session.
1813
1883
  * On create, sets the session workspace. On resume (continuation hit),
@@ -1928,11 +1998,14 @@ export interface ToolCallOutcome {
1928
1998
  /** Present when the call ran inside an existing session. */
1929
1999
  sessionId?: string;
1930
2000
  /**
1931
- * Present (true) when a session-bound call could not materialize the
1932
- * session's harness cwd and ran in a scratch workspace instead. The
1933
- * session identity still applied (read-effect calls only get here), but
1934
- * `ctx.workspaceDir` was not the session workspace — callers rendering
1935
- * results as session state should surface this.
2001
+ * Present (true) when a session-bound call could not materialize a
2002
+ * session-owned harness cwd and ran in a scratch workspace instead.
2003
+ * The session identity still applied (read-effect calls only get here),
2004
+ * but `ctx.workspaceDir` was not the session workspace — callers
2005
+ * rendering results as session state should surface this.
2006
+ *
2007
+ * A shared `local.workspaceDir` the host cannot create (a phantom path
2008
+ * like `/repo`) is kept as-is and does not set this flag.
1936
2009
  */
1937
2010
  scratchWorkspace?: true;
1938
2011
  }
@@ -2187,6 +2260,18 @@ export interface ChannelStartArgs {
2187
2260
  auth: AuthContext | null,
2188
2261
  options?: { asSessionOwner?: boolean }
2189
2262
  ): Promise<PendingApproval>;
2263
+ /**
2264
+ * Mark a parked MCP auth as connected or cancelled. Channel packs
2265
+ * (Slack "Connected") use this; the public OAuth callback also
2266
+ * resolves after `finishAuth`.
2267
+ */
2268
+ resolveAuth(
2269
+ sessionId: string,
2270
+ callId: string,
2271
+ decision: ApprovalDecision,
2272
+ auth: AuthContext | null,
2273
+ options?: { asSessionOwner?: boolean }
2274
+ ): Promise<PendingAuth>;
2190
2275
  /**
2191
2276
  * Server log sink (same as {@link ServeOptions.logger}). Channel packs
2192
2277
  * should prefer this over `console.*` so CLI/eval hosts can redirect.
@@ -0,0 +1,39 @@
1
+ # Living AGENTS.md
2
+
3
+ Keeps `AGENTS.md` current from last week's merged pull requests and the
4
+ listed Slack channels. Parks an update until a person approves it, then
5
+ opens a draft follow-up PR. Chores stay quiet. Same-base updates stack
6
+ on `agents-md/<base>`.
7
+
8
+ ```bash
9
+ npx @cursor/july init ./agents-md --template agents-md
10
+ ```
11
+
12
+ `init` asks which repo to watch and which Slack channels to read. Skip
13
+ the prompt with `--var repos=owner/repo --var slack=#eng-api`.
14
+
15
+ ## Run
16
+
17
+ Connect GitHub in Cursor for that repo. Create the Slack app and invite
18
+ the bot to each listed channel, including private ones. Then sign the
19
+ host in:
20
+
21
+ ```bash
22
+ agent-sdk login
23
+ agent-sdk slack create --dir .
24
+ agent-sdk dev
25
+ ```
26
+
27
+ Schedules do not fire under `dev`. Dispatch the weekly job:
28
+
29
+ ```bash
30
+ curl -X POST http://127.0.0.1:3000/v1/dev/schedules/weekly
31
+ ```
32
+
33
+ Or run `/queue/run` in the playground.
34
+
35
+ ## Files
36
+
37
+ - `agent/lib/config.ts`: repo and Slack channels
38
+ - `agent/instructions.md`: what counts as an AGENTS.md update
39
+ - `evals/agents.eval.ts`: skip and update smoke cases