@cursor/july 0.1.99 → 0.1.100

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 (267) hide show
  1. package/AGENTS.md +4 -2
  2. package/dist/channels/github/defaults.d.ts.map +1 -1
  3. package/dist/channels/github/defaults.js +28 -3
  4. package/dist/channels/github/progress.d.ts +7 -0
  5. package/dist/channels/github/progress.d.ts.map +1 -1
  6. package/dist/channels/slack/api.d.ts +16 -7
  7. package/dist/channels/slack/api.d.ts.map +1 -1
  8. package/dist/channels/slack/api.js +29 -13
  9. package/dist/channels/slack/constants.d.ts +6 -0
  10. package/dist/channels/slack/constants.d.ts.map +1 -1
  11. package/dist/channels/slack/constants.js +6 -0
  12. package/dist/channels/slack/defaults.d.ts +9 -4
  13. package/dist/channels/slack/defaults.d.ts.map +1 -1
  14. package/dist/channels/slack/defaults.js +154 -76
  15. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  16. package/dist/channels/slack/dispatch.js +3 -3
  17. package/dist/channels/slack/inbound.d.ts +9 -0
  18. package/dist/channels/slack/inbound.d.ts.map +1 -1
  19. package/dist/channels/slack/inbound.js +14 -0
  20. package/dist/channels/slack/index.d.ts +1 -0
  21. package/dist/channels/slack/index.d.ts.map +1 -1
  22. package/dist/channels/slack/index.js +1 -0
  23. package/dist/channels/slack/live-delivery.d.ts +5 -0
  24. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  25. package/dist/channels/slack/live-delivery.js +107 -19
  26. package/dist/channels/slack/reasoning-card.d.ts +38 -0
  27. package/dist/channels/slack/reasoning-card.d.ts.map +1 -0
  28. package/dist/channels/slack/reasoning-card.js +104 -0
  29. package/dist/channels/slack/redact.d.ts +2 -0
  30. package/dist/channels/slack/redact.d.ts.map +1 -0
  31. package/dist/channels/slack/redact.js +5 -0
  32. package/dist/channels/slack/reply-options.d.ts +40 -0
  33. package/dist/channels/slack/reply-options.d.ts.map +1 -0
  34. package/dist/channels/slack/reply-options.js +150 -0
  35. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  36. package/dist/channels/slack/slack-channel.js +8 -4
  37. package/dist/channels/slack/stream.d.ts +22 -10
  38. package/dist/channels/slack/stream.d.ts.map +1 -1
  39. package/dist/channels/slack/stream.js +9 -16
  40. package/dist/channels/slack/tool-cards.d.ts +22 -0
  41. package/dist/channels/slack/tool-cards.d.ts.map +1 -0
  42. package/dist/channels/slack/tool-cards.js +178 -0
  43. package/dist/channels/slack/types.d.ts +145 -6
  44. package/dist/channels/slack/types.d.ts.map +1 -1
  45. package/dist/docs/404.html +2 -2
  46. package/dist/docs/ab.html +6 -6
  47. package/dist/docs/ab.md +1 -1
  48. package/dist/docs/assets/{ab.md.DJo5r4R-.js → ab.md.mlVgqvSk.js} +1 -1
  49. package/dist/docs/assets/{app.BplEAZ3S.js → app.DZ1e0Ycq.js} +1 -1
  50. package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.js → building-with-agents.md.CUSWxlP_.js} +2 -2
  51. package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +1 -0
  52. package/dist/docs/assets/chunks/{VPLocalSearchBox.CHXyv4wP.js → VPLocalSearchBox.l8omwc6D.js} +1 -1
  53. package/dist/docs/assets/chunks/{theme.BTcsZmjQ.js → theme.JVcD6gel.js} +2 -2
  54. package/dist/docs/assets/{evals.md.lfJoEVc8.js → evals.md.CPzDAwoH.js} +1 -1
  55. package/dist/docs/assets/{guides_github.md.Cnh2mL4a.js → guides_github.md.BtPr9GaP.js} +1 -1
  56. package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.js → guides_mcp-oauth.md.Dp6cDP7f.js} +1 -1
  57. package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.js → guides_opentelemetry.md.BVTXDCRg.js} +2 -2
  58. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.js → guides_slack.md.9oHPye9o.js} +19 -3
  59. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.lean.js → guides_slack.md.9oHPye9o.lean.js} +1 -1
  60. package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +4 -0
  61. package/dist/docs/assets/{index.md.CVeRUOeZ.js → index.md.Bb4k8kUm.js} +1 -1
  62. package/dist/docs/assets/{quickstart.md.Nj_LjW_a.js → quickstart.md.DdQOF7Y8.js} +1 -1
  63. package/dist/docs/assets/{reference_connections.md.DxldvyIB.js → reference_connections.md.BiGoBAk2.js} +1 -1
  64. package/dist/docs/assets/scaffolding-agents.md.em43xlY1.js +1 -0
  65. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +26 -0
  66. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +1 -0
  67. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.js +8 -0
  68. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.lean.js +1 -0
  69. package/dist/docs/assets/skills_debug.md.CDbPhHfg.js +1 -0
  70. package/dist/docs/assets/skills_debug.md.CDbPhHfg.lean.js +1 -0
  71. package/dist/docs/assets/skills_evals.md.723kpUmA.js +25 -0
  72. package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +1 -0
  73. package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +1 -0
  74. package/dist/docs/assets/skills_framework-map.md.BTi817yv.lean.js +1 -0
  75. package/dist/docs/assets/skills_github.md.D0JahM8c.js +16 -0
  76. package/dist/docs/assets/skills_github.md.D0JahM8c.lean.js +1 -0
  77. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +7 -0
  78. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +1 -0
  79. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +1 -0
  80. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +1 -0
  81. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +18 -0
  82. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +1 -0
  83. package/dist/docs/assets/skills_otel.md.CgiZryR3.js +8 -0
  84. package/dist/docs/assets/skills_otel.md.CgiZryR3.lean.js +1 -0
  85. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +20 -0
  86. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +1 -0
  87. package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.js → troubleshooting.md.Cus_YZga.js} +1 -1
  88. package/dist/docs/building-with-agents.html +6 -6
  89. package/dist/docs/building-with-agents.md +14 -11
  90. package/dist/docs/concepts.html +4 -4
  91. package/dist/docs/deployment.html +4 -4
  92. package/dist/docs/evals.html +6 -6
  93. package/dist/docs/evals.md +1 -1
  94. package/dist/docs/guides/agent-to-agent.html +4 -4
  95. package/dist/docs/guides/cloud-runtime.html +4 -4
  96. package/dist/docs/guides/convert-automation.html +4 -4
  97. package/dist/docs/guides/github.html +5 -5
  98. package/dist/docs/guides/github.md +1 -1
  99. package/dist/docs/guides/human-in-the-loop.html +4 -4
  100. package/dist/docs/guides/mcp-oauth.html +5 -5
  101. package/dist/docs/guides/mcp-oauth.md +1 -1
  102. package/dist/docs/guides/opentelemetry.html +7 -7
  103. package/dist/docs/guides/opentelemetry.md +2 -2
  104. package/dist/docs/guides/slack.html +22 -6
  105. package/dist/docs/guides/slack.md +80 -1
  106. package/dist/docs/guides/webhooks.html +5 -5
  107. package/dist/docs/hashmap.json +1 -1
  108. package/dist/docs/hillclimbing.html +6 -6
  109. package/dist/docs/hillclimbing.md +5 -5
  110. package/dist/docs/index.html +6 -6
  111. package/dist/docs/index.md +1 -1
  112. package/dist/docs/llms-full.txt +1041 -30
  113. package/dist/docs/llms.txt +14 -0
  114. package/dist/docs/quickstart.html +5 -5
  115. package/dist/docs/quickstart.md +1 -1
  116. package/dist/docs/reference/agent-config.html +4 -4
  117. package/dist/docs/reference/artifacts.html +4 -4
  118. package/dist/docs/reference/channels.html +4 -4
  119. package/dist/docs/reference/cli.html +4 -4
  120. package/dist/docs/reference/connections.html +6 -6
  121. package/dist/docs/reference/connections.md +1 -1
  122. package/dist/docs/reference/hooks.html +4 -4
  123. package/dist/docs/reference/http-api.html +4 -4
  124. package/dist/docs/reference/instructions.html +4 -4
  125. package/dist/docs/reference/playground.html +4 -4
  126. package/dist/docs/reference/project-layout.html +4 -4
  127. package/dist/docs/reference/prompt.html +4 -4
  128. package/dist/docs/reference/schedules.html +4 -4
  129. package/dist/docs/reference/sessions.html +4 -4
  130. package/dist/docs/reference/skills.html +4 -4
  131. package/dist/docs/reference/subagents.html +4 -4
  132. package/dist/docs/reference/tools.html +4 -4
  133. package/dist/docs/scaffolding-agents.html +5 -5
  134. package/dist/docs/scaffolding-agents.md +3 -3
  135. package/dist/docs/skills/ab.html +52 -0
  136. package/dist/docs/skills/ab.md +50 -0
  137. package/dist/docs/skills/create-agent.html +34 -0
  138. package/dist/docs/skills/create-agent.md +160 -0
  139. package/dist/docs/skills/debug.html +27 -0
  140. package/dist/docs/skills/debug.md +36 -0
  141. package/dist/docs/skills/evals.html +51 -0
  142. package/dist/docs/skills/evals.md +99 -0
  143. package/dist/docs/skills/framework-map.html +27 -0
  144. package/dist/docs/skills/framework-map.md +95 -0
  145. package/dist/docs/skills/github.html +42 -0
  146. package/dist/docs/skills/github.md +93 -0
  147. package/dist/docs/skills/hillclimb.html +33 -0
  148. package/dist/docs/skills/hillclimb.md +55 -0
  149. package/dist/docs/skills/index.html +27 -0
  150. package/dist/docs/skills/index.md +21 -0
  151. package/dist/docs/skills/mcp-auth.html +44 -0
  152. package/dist/docs/skills/mcp-auth.md +76 -0
  153. package/dist/docs/skills/otel.html +34 -0
  154. package/dist/docs/skills/otel.md +48 -0
  155. package/dist/docs/skills/setup-slack.html +46 -0
  156. package/dist/docs/skills/setup-slack.md +141 -0
  157. package/dist/docs/storage.html +4 -4
  158. package/dist/docs/templates/agentic-owners.html +4 -4
  159. package/dist/docs/templates/agents-md.html +4 -4
  160. package/dist/docs/templates/code-wiki.html +4 -4
  161. package/dist/docs/templates/demo.html +4 -4
  162. package/dist/docs/templates/pr-autofixer.html +4 -4
  163. package/dist/docs/templates/security-help.html +4 -4
  164. package/dist/docs/templates/security-reviewer.html +4 -4
  165. package/dist/docs/templates/triage.html +4 -4
  166. package/dist/docs/troubleshooting.html +5 -5
  167. package/dist/docs/troubleshooting.md +1 -1
  168. package/dist/files-backends/cursor-hosted.d.ts +6 -0
  169. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  170. package/dist/files-backends/cursor-hosted.js +6 -9
  171. package/dist/internal/cli-deploy.js +2 -2
  172. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  173. package/dist/internal/conversation-mirror.js +3 -4
  174. package/dist/internal/cursor/hosted-store-secrets.d.ts +15 -0
  175. package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -0
  176. package/dist/internal/cursor/hosted-store-secrets.js +48 -0
  177. package/dist/internal/deploy-client.d.ts +6 -6
  178. package/dist/internal/deploy-client.js +7 -7
  179. package/dist/internal/discovery.d.ts.map +1 -1
  180. package/dist/internal/discovery.js +11 -1
  181. package/dist/internal/framework-file-storage.d.ts +12 -5
  182. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  183. package/dist/internal/framework-file-storage.js +36 -5
  184. package/dist/internal/framework-storage-selection.d.ts +12 -12
  185. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  186. package/dist/internal/framework-storage-selection.js +33 -39
  187. package/dist/internal/session-run-log.d.ts +3 -3
  188. package/dist/internal/session-run-log.d.ts.map +1 -1
  189. package/dist/internal/session-run-log.js +6 -7
  190. package/dist/internal/storage-coordinator.d.ts +0 -6
  191. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  192. package/dist/internal/storage-coordinator.js +1 -9
  193. package/dist/playground/assets/index-BszoQDc6.css +1 -0
  194. package/dist/playground/assets/{index-jzNbJENa.js → index-DVs98vPL.js} +1 -1
  195. package/dist/playground/index.html +2 -2
  196. package/dist/storage-backends/cursor-hosted-v2.d.ts +83 -0
  197. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -0
  198. package/dist/storage-backends/cursor-hosted-v2.js +164 -0
  199. package/dist/storage-backends/cursor-hosted.d.ts +6 -0
  200. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  201. package/dist/storage-backends/cursor-hosted.js +6 -1
  202. package/dist/types.d.ts +5 -0
  203. package/dist/types.d.ts.map +1 -1
  204. package/docs/README.md +1 -1
  205. package/docs/ab.md +1 -1
  206. package/docs/building-with-agents.md +14 -11
  207. package/docs/evals.md +1 -1
  208. package/docs/guides/github.md +1 -1
  209. package/docs/guides/mcp-oauth.md +1 -1
  210. package/docs/guides/opentelemetry.md +2 -2
  211. package/docs/guides/slack.md +80 -1
  212. package/docs/hillclimbing.md +5 -5
  213. package/docs/quickstart.md +1 -1
  214. package/docs/reference/connections.md +1 -1
  215. package/docs/scaffolding-agents.md +3 -3
  216. package/docs/skills/index.md +26 -0
  217. package/docs/troubleshooting.md +1 -1
  218. package/package.json +1 -1
  219. package/src/channels/github/defaults.ts +36 -3
  220. package/src/channels/github/progress.ts +7 -0
  221. package/src/channels/slack/api.ts +35 -17
  222. package/src/channels/slack/constants.ts +6 -0
  223. package/src/channels/slack/defaults.ts +173 -92
  224. package/src/channels/slack/dispatch.ts +8 -1
  225. package/src/channels/slack/inbound.ts +17 -0
  226. package/src/channels/slack/index.ts +1 -0
  227. package/src/channels/slack/live-delivery.ts +131 -20
  228. package/src/channels/slack/reasoning-card.ts +140 -0
  229. package/src/channels/slack/redact.ts +6 -0
  230. package/src/channels/slack/reply-options.ts +229 -0
  231. package/src/channels/slack/slack-channel.ts +7 -2
  232. package/src/channels/slack/stream.ts +31 -24
  233. package/src/channels/slack/tool-cards.ts +221 -0
  234. package/src/channels/slack/types.ts +159 -6
  235. package/src/files-backends/cursor-hosted.ts +15 -5
  236. package/src/internal/cli-deploy.ts +2 -2
  237. package/src/internal/conversation-mirror.ts +3 -8
  238. package/src/internal/cursor/hosted-store-secrets.ts +72 -0
  239. package/src/internal/deploy-client.ts +10 -10
  240. package/src/internal/discovery.ts +9 -1
  241. package/src/internal/framework-file-storage.ts +41 -5
  242. package/src/internal/framework-storage-selection.ts +31 -44
  243. package/src/internal/session-run-log.ts +6 -11
  244. package/src/internal/storage-coordinator.ts +1 -11
  245. package/src/storage-backends/cursor-hosted-v2.ts +219 -0
  246. package/src/storage-backends/cursor-hosted.ts +6 -1
  247. package/src/types.ts +5 -0
  248. package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +0 -1
  249. package/dist/docs/assets/hillclimbing.md.DhESf3OO.js +0 -4
  250. package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +0 -1
  251. package/dist/internal/null-kv-storage.d.ts +0 -48
  252. package/dist/internal/null-kv-storage.d.ts.map +0 -1
  253. package/dist/internal/null-kv-storage.js +0 -58
  254. package/dist/playground/assets/index-D7rGZNjy.css +0 -1
  255. package/src/internal/null-kv-storage.ts +0 -74
  256. /package/dist/docs/assets/{ab.md.DJo5r4R-.lean.js → ab.md.mlVgqvSk.lean.js} +0 -0
  257. /package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.lean.js → building-with-agents.md.CUSWxlP_.lean.js} +0 -0
  258. /package/dist/docs/assets/{evals.md.lfJoEVc8.lean.js → evals.md.CPzDAwoH.lean.js} +0 -0
  259. /package/dist/docs/assets/{guides_github.md.Cnh2mL4a.lean.js → guides_github.md.BtPr9GaP.lean.js} +0 -0
  260. /package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.lean.js → guides_mcp-oauth.md.Dp6cDP7f.lean.js} +0 -0
  261. /package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.lean.js → guides_opentelemetry.md.BVTXDCRg.lean.js} +0 -0
  262. /package/dist/docs/assets/{hillclimbing.md.DhESf3OO.lean.js → hillclimbing.md.CpTGTCle.lean.js} +0 -0
  263. /package/dist/docs/assets/{index.md.CVeRUOeZ.lean.js → index.md.Bb4k8kUm.lean.js} +0 -0
  264. /package/dist/docs/assets/{quickstart.md.Nj_LjW_a.lean.js → quickstart.md.DdQOF7Y8.lean.js} +0 -0
  265. /package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.BiGoBAk2.lean.js} +0 -0
  266. /package/dist/docs/assets/{scaffolding-agents.md.D7UUkWw0.lean.js → scaffolding-agents.md.em43xlY1.lean.js} +0 -0
  267. /package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.lean.js → troubleshooting.md.Cus_YZga.lean.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Thin client for the Agent Serve deployment management API
3
3
  * (`/internal/agent-serve/deployments` on the Cursor backend) and the v2
4
- * AgentSDK accept path (`/internal/agentkit/deployments`). Pure
4
+ * AgentSDK accept path (`/internal/agentsdk/deployments`). Pure
5
5
  * request/response + error mapping — no console I/O, no polling loops;
6
6
  * rendering lives in `cli-deploy.ts`.
7
7
  *
@@ -214,7 +214,7 @@ export interface StopAccepted {
214
214
  export type DeleteAccepted = StopAccepted;
215
215
 
216
216
  /**
217
- * `POST /internal/agentkit/deployments` 202 body. Distinct from v1
217
+ * `POST /internal/agentsdk/deployments` 202 body. Distinct from v1
218
218
  * {@link DeployAccepted}: the v2 control plane returns catalog ids, not
219
219
  * an engine alias or one-shot alias token.
220
220
  */
@@ -234,7 +234,7 @@ export interface AgentkitDeployComponent {
234
234
  agentPath?: string;
235
235
  }
236
236
 
237
- /** Customer-visible v2 deploy status (`GET /internal/agentkit/deployments/:slug`). */
237
+ /** Customer-visible v2 deploy status (`GET /internal/agentsdk/deployments/:slug`). */
238
238
  export type AgentkitCustomerStatus =
239
239
  | "pending"
240
240
  | "deploying"
@@ -273,7 +273,7 @@ export const TERMINAL_AGENTKIT_DEPLOY_STATUSES: ReadonlySet<AgentkitCustomerStat
273
273
  new Set(["running", "failed", "stopped"]);
274
274
 
275
275
  /**
276
- * `POST /internal/agentkit/deployments/:slug/stop` 202 body. Like v1
276
+ * `POST /internal/agentsdk/deployments/:slug/stop` 202 body. Like v1
277
277
  * {@link StopAccepted} but keyed by catalog ids instead of the numeric
278
278
  * deployment row id.
279
279
  */
@@ -594,7 +594,7 @@ export class AgentServeDeployClient {
594
594
 
595
595
  /**
596
596
  * Create or redeploy onto the v2 control plane
597
- * (`POST /internal/agentkit/deployments`). 202 means accepted; poll
597
+ * (`POST /internal/agentsdk/deployments`). 202 means accepted; poll
598
598
  * {@link getAgentkitDeploy} until a terminal status. `components` deploys
599
599
  * one application with several release components (one per agent
600
600
  * directory); it is mutually exclusive with `agentPath`.
@@ -625,7 +625,7 @@ export class AgentServeDeployClient {
625
625
  }
626
626
  const raw = await this.request({
627
627
  method: "POST",
628
- path: "/internal/agentkit/deployments",
628
+ path: "/internal/agentsdk/deployments",
629
629
  body: {
630
630
  teamId: args.teamId,
631
631
  slug: args.slug,
@@ -650,14 +650,14 @@ export class AgentServeDeployClient {
650
650
  }): Promise<AgentkitDeployStatus> {
651
651
  const raw = await this.request({
652
652
  method: "GET",
653
- path: `/internal/agentkit/deployments/${encodeURIComponent(args.slug)}?teamId=${args.teamId}`,
653
+ path: `/internal/agentsdk/deployments/${encodeURIComponent(args.slug)}?teamId=${args.teamId}`,
654
654
  context: { verb: "get deployment", slug: args.slug },
655
655
  });
656
656
  return agentkitDeployStatusSchema.parse(raw);
657
657
  }
658
658
 
659
659
  /**
660
- * Stop a v2 deployment (`POST /internal/agentkit/deployments/:slug/stop`).
660
+ * Stop a v2 deployment (`POST /internal/agentsdk/deployments/:slug/stop`).
661
661
  * 202 means accepted; poll {@link getAgentkitDeploy} until `stopped`.
662
662
  */
663
663
  async stopAgentkit(args: {
@@ -666,7 +666,7 @@ export class AgentServeDeployClient {
666
666
  }): Promise<AgentkitStopAccepted> {
667
667
  const raw = await this.request({
668
668
  method: "POST",
669
- path: `/internal/agentkit/deployments/${encodeURIComponent(args.slug)}/stop?teamId=${args.teamId}`,
669
+ path: `/internal/agentsdk/deployments/${encodeURIComponent(args.slug)}/stop?teamId=${args.teamId}`,
670
670
  context: { verb: "stop", slug: args.slug },
671
671
  });
672
672
  return agentkitStopAcceptedSchema.parse(raw);
@@ -977,7 +977,7 @@ function mapErrorResponse(
977
977
  // (api2 vs api.cursor.com), not a missing deployment / closed gate.
978
978
  if (/Route \S+ not found/i.test(bodyText)) {
979
979
  return new DeployApiError(
980
- `Agent Serve deploy API not found on this host — use the default api.cursor.com (unset CURSOR_API_BASE_URL), or point CURSOR_API_BASE_URL at a backend that mounts /internal/agent-serve/* and /internal/agentkit/*.`,
980
+ `Agent Serve deploy API not found on this host — use the default api.cursor.com (unset CURSOR_API_BASE_URL), or point CURSOR_API_BASE_URL at a backend that mounts /internal/agent-serve/* and /internal/agentsdk/*.`,
981
981
  404
982
982
  );
983
983
  }
@@ -1928,7 +1928,15 @@ async function loadChannels(
1928
1928
  });
1929
1929
  continue;
1930
1930
  }
1931
- channels.push({ id, definition: mod.default as ChannelDefinition });
1931
+ const definition = mod.default as ChannelDefinition;
1932
+ for (const notice of definition.meta?.deprecations ?? []) {
1933
+ ctx.diagnostics.push({
1934
+ severity: "warning",
1935
+ path: displayPath(ctx, entryPath),
1936
+ message: notice,
1937
+ });
1938
+ }
1939
+ channels.push({ id, definition });
1932
1940
  }
1933
1941
  return { channels, httpChannelDefinition };
1934
1942
  }
@@ -167,11 +167,8 @@ function decodeDocument(key: string, bytes: Uint8Array): JsonValue {
167
167
  * Split one storage core by key kind: framework session state to `files`,
168
168
  * everything else to `kv`. Spread over the KV backend when building the
169
169
  * full definition so its `evals` / `abs` groups (and the cursor-hosted
170
- * marker) ride along untouched. A KV `cas` group must not be spread as-is:
171
- * conditional writes run on a KV database row, so one over a `session/` or
172
- * `continuation/` key would read and write a different store than the
173
- * routed plain core — silent split-brain. Nothing in the package CASes
174
- * those kinds today.
170
+ * marker) ride along untouched; wrap the KV `cas` group with
171
+ * {@link frameworkGuardedCas} rather than spreading it as-is.
175
172
  */
176
173
  export function composeFrameworkStorage(input: {
177
174
  kv: FileSinkStorageCore;
@@ -192,3 +189,42 @@ export function composeFrameworkStorage(input: {
192
189
  listNewest: undefined,
193
190
  };
194
191
  }
192
+
193
+ /**
194
+ * The KV backend's conditional writes, refusing framework-file keys.
195
+ *
196
+ * CAS runs on the KV proxy (a database row version); the plain core routes
197
+ * framework session state to the file store. A future coordination path
198
+ * that CASes a `session/` or `continuation/` key would otherwise read and
199
+ * write a different store than the plain path — silent split-brain. Fail
200
+ * loudly instead; nothing in the package CASes those kinds today.
201
+ */
202
+ export function frameworkGuardedCas(
203
+ cas: NonNullable<StorageConfig["cas"]>
204
+ ): NonNullable<StorageConfig["cas"]> {
205
+ const refuse = (key: string): void => {
206
+ if (isFrameworkFileKey(key)) {
207
+ throw new Error(
208
+ `framework file storage: conditional writes are KV-only, but "${key}" routes to the framework file store`
209
+ );
210
+ }
211
+ };
212
+ return {
213
+ getWithVersion: (key, ctx) => {
214
+ refuse(key);
215
+ return cas.getWithVersion(key, ctx);
216
+ },
217
+ putIfAbsent: (key, value, ctx) => {
218
+ refuse(key);
219
+ return cas.putIfAbsent(key, value, ctx);
220
+ },
221
+ putIfVersion: (key, value, expectedVersion, ctx) => {
222
+ refuse(key);
223
+ return cas.putIfVersion(key, value, expectedVersion, ctx);
224
+ },
225
+ listKeys: (prefix, ctx) => {
226
+ refuse(prefix);
227
+ return cas.listKeys(prefix, ctx);
228
+ },
229
+ };
230
+ }
@@ -18,18 +18,18 @@
18
18
  * - **Cursor-managed hosting** (the deployment-generation environment
19
19
  * variable is set, same signal that registers `GET /v1/manifest`):
20
20
  * the deployment's **framework-level file store**
21
- * (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`) holds session records, event
22
- * transcripts, and the continuation index — file-shaped state on file
23
- * storage, apart from the author-facing user store. The control-plane KV
24
- * proxy is *not* used: it authorizes by mapping a pod service account to
25
- * a v1 deployment row, which no v2 deployment has, so every call 403s and
26
- * fails the delivery that read it. The KV half is inert until the proxy
27
- * resolves v2 deployments (see null-kv-storage.ts). Without a framework
28
- * store (a deploy predating framework-store provisioning) there is
29
- * nothing left to mirror to, so the state root is again the only copy.
30
- * The API key resolves through the full credential chain on every call
31
- * because hosted freeze snapshots listen unsigned and the binder drops
32
- * the key file after restore.
21
+ * (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`, bound at task time) holds
22
+ * session records, event transcripts, and the continuation index —
23
+ * file-shaped state on file storage, apart from the author-facing user
24
+ * store. Author `host.kv`, eval runs, A/B samples, and conditional writes
25
+ * ride the AgentSDK v2 KV proxy (cursor-hosted-v2.ts), which resolves the
26
+ * pod service account to the factorydb deployment row (the v1 Bugbot
27
+ * proxy cannot resolve v2 pods at all). Framework session state never
28
+ * routes to the KV proxy the composite splits by key kind — so
29
+ * transcripts stay off the author-reachable KV namespace. The API key
30
+ * resolves through the full credential chain on every call because hosted
31
+ * freeze snapshots listen unsigned and the binder drops the key file
32
+ * after restore.
33
33
  * - **Self-hosted**: no mirror. `--state-root` is the durable copy, which
34
34
  * is correct when the operator owns the disk.
35
35
  *
@@ -47,17 +47,15 @@ import {
47
47
  cursorHostedFiles,
48
48
  } from "../files-backends/cursor-hosted.js";
49
49
  import { defineStorage, type StorageDefinition } from "../storage.js";
50
- import { CURSOR_HOSTED_STORAGE } from "../storage-backends/cursor-hosted.js";
50
+ import { cursorHostedStorageV2 } from "../storage-backends/cursor-hosted-v2.js";
51
51
  import type { AgentArchitecture } from "../types.js";
52
52
  import { resolveApiKeySync } from "./cursor/credentials.js";
53
53
  import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
54
54
  import {
55
55
  composeFrameworkStorage,
56
56
  fileSinkStorageCore,
57
+ frameworkGuardedCas,
57
58
  } from "./framework-file-storage.js";
58
- import { nullKvStorage } from "./null-kv-storage.js";
59
-
60
- const cursorHostedMarker = { [CURSOR_HOSTED_STORAGE]: true } as const;
61
59
 
62
60
  export interface FrameworkStorageSelectionInput {
63
61
  /** `agent/storage.ts`, when the author wrote one (v1 only: discovery rejects it on v2). */
@@ -100,44 +98,33 @@ export function selectFrameworkStorageDefinition(
100
98
  // comes up). Follow-ups restore lazily by continuation or session id;
101
99
  // GET /v1/sessions lists from the sink either way.
102
100
  const policy = { restore: "off" } as const;
103
- const frameworkStoreId = cursorFrameworkStoreSourceId(
104
- env as NodeJS.ProcessEnv
105
- );
106
- if (frameworkStoreId === undefined) {
107
- // Nothing to mirror to: the KV proxy rejects v2 service accounts, so a
108
- // definition over it would fail every delivery that reads it. The state
109
- // root is the durable copy, as when self-hosted.
110
- return undefined;
111
- }
112
- // Full chain (env → key file → stored login): frozen engines listen
113
- // unsigned and bind CURSOR_API_KEY_FILE at task time, after this
101
+ const envSnapshot = env as NodeJS.ProcessEnv;
102
+ // Full chain (env bind file → stored login): frozen engines listen
103
+ // unsigned and bind store ids + CURSOR_API_KEY at task time, after this
114
104
  // definition is constructed.
115
105
  const resolveApiKey = (): string | undefined => resolveApiKeySync()?.apiKey;
116
- // Framework session state on the framework-level file store, which
117
- // authorizes by store source id and so works for v2. Everything the KV
118
- // proxy used to serve author kv, eval runs, A/B samples, conditional
119
- // writes is inert; `defineStorage` derives the eval/A/B tables over the
120
- // core, which means that bookkeeping reads back empty rather than 403ing.
121
- //
122
- // Restoring `cursorHostedStorage()` here once the proxy resolves v2
123
- // deployments also means restoring the guard its `cas` group needs: a
124
- // conditional write over a `session/` or `continuation/` key would run on
125
- // the KV database while the plain core routes that key to the file store.
126
- const kv = nullKvStorage();
106
+ // v2 pods carry a factorydb-bound service account, which the v1 Bugbot
107
+ // storage proxy cannot resolve; author KV, CAS coordination, and the
108
+ // eval/A-B tables speak the AgentSDK v2 KV proxy instead. It also carries
109
+ // the cursor-hosted marker, so GET /v1/sessions prefers the durable list
110
+ // (session records are on the framework store, which the composed core
111
+ // lists).
112
+ const kv = cursorHostedStorageV2({ resolveApiKey });
127
113
  return defineStorage({
128
114
  name: "cursor-hosted (framework files)",
129
115
  policy,
130
- // GET /v1/sessions still prefers the durable list: session records live
131
- // on the framework store, which the composed core lists. Spread rather
132
- // than named, the way cursorHostedStorage carries it: the marker is a
133
- // platform stamp, not part of the authored config surface.
134
- ...cursorHostedMarker,
135
116
  ...kv,
136
117
  ...composeFrameworkStorage({
137
118
  kv,
138
119
  files: fileSinkStorageCore(
139
- cursorHostedFiles({ storeSourceId: frameworkStoreId, resolveApiKey })
120
+ cursorHostedFiles({
121
+ resolveStoreSourceId: () => cursorFrameworkStoreSourceId(envSnapshot),
122
+ resolveApiKey,
123
+ })
140
124
  ),
141
125
  }),
126
+ // CAS stays on the KV proxy but must refuse framework-file keys, or a
127
+ // future coordination path would split-brain against the plain core.
128
+ cas: frameworkGuardedCas(kv.cas),
142
129
  });
143
130
  }
@@ -547,9 +547,9 @@ export function createSessionRunLogStore(input: {
547
547
 
548
548
  /**
549
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.
550
+ * engines (generation env set). Store ids resolve lazily from env or the
551
+ * task-bind files under `/run/cursor/secrets`. Self-hosted and v1 stay on
552
+ * local disk / today's behavior.
553
553
  */
554
554
  export function selectSessionRunLogStore(input: {
555
555
  project: AgentProject;
@@ -561,18 +561,13 @@ export function selectSessionRunLogStore(input: {
561
561
  return undefined;
562
562
  }
563
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
- ) {
564
+ if (env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined) {
571
565
  return undefined;
572
566
  }
567
+ const envSnapshot = env as NodeJS.ProcessEnv;
573
568
  return createSessionRunLogStore({
574
569
  sink: cursorHostedFiles({
575
- storeSourceId: frameworkStoreId,
570
+ resolveStoreSourceId: () => cursorFrameworkStoreSourceId(envSnapshot),
576
571
  resolveApiKey: () => resolveApiKeySync()?.apiKey,
577
572
  }),
578
573
  agentName: input.project.name,
@@ -38,7 +38,6 @@ import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
38
38
  import type { ABSnapshot } from "./ab-snapshot.js";
39
39
  import { describeError } from "./describe-error.js";
40
40
  import type { EvalRunStorage } from "./eval-run-store.js";
41
- import { isAuthorKvUnsupported } from "./null-kv-storage.js";
42
41
  import type {
43
42
  AuthorKvStore,
44
43
  EvalAbStore,
@@ -469,18 +468,9 @@ export class StorageCoordinator
469
468
  /**
470
469
  * Whether the sink can serve awaited author reads/writes (`get` is
471
470
  * 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.
478
471
  */
479
472
  get supportsAuthorKv(): boolean {
480
- return (
481
- this.definition.get !== undefined &&
482
- !isAuthorKvUnsupported(this.definition)
483
- );
473
+ return this.definition.get !== undefined;
484
474
  }
485
475
 
486
476
  /**
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Cursor-managed durable KV for hosted **architecture v2** agents.
3
+ *
4
+ * Talks to the AgentSDK v2 KV proxy
5
+ * (`POST /internal/agentsdk/kv/*`) using the engine's pod
6
+ * `CURSOR_API_KEY`. The server resolves the v2 deployment from that service
7
+ * account (factorydb `agentsdk_deployment`) and persists rows in factorydb
8
+ * `agentsdk_kv` — v1's Bugbot-backed `/internal/agent-serve/storage/*`
9
+ * routes cannot resolve a v2 pod credential at all.
10
+ *
11
+ * The v2 wire protocol is four routes, not v1's eight:
12
+ *
13
+ * - `POST /internal/agentsdk/kv/get`
14
+ * `{ key }` → `{ found, value, version }` — reads always carry the CAS
15
+ * version token ({@link KvV2GetResponse}).
16
+ * - `POST /internal/agentsdk/kv/put`
17
+ * `{ key, value, ifAbsent? | ifVersion? }` → `{ ok, version, current }`
18
+ * ({@link KvV2PutResponse}) — one write primitive: last-write-wins when
19
+ * unconditional (still bumps the token), atomic create-if-absent with
20
+ * `ifAbsent: true`, atomic compare-and-swap with `ifVersion`.
21
+ * - `POST /internal/agentsdk/kv/delete` `{ key }` → `{ ok }`.
22
+ * - `POST /internal/agentsdk/kv/list`
23
+ * `{ prefix, limit?, cursor?, keysOnly? }` → `{ entries, nextCursor }`
24
+ * ({@link KvV2ListResponse}) — ascending key order with keyset
25
+ * pagination. `list` / `listKeys` below drain every page, so the v1
26
+ * truncated-scan failure mode does not exist here.
27
+ *
28
+ * Eval runs and A/B samples still ride the v1 storage proxy's dedicated
29
+ * tables (`evals` / `abs` below); moving them to factorydb is a separate
30
+ * follow-up from the KV cutover.
31
+ *
32
+ * This backend is platform-selected for architecture v2
33
+ * (framework-storage-selection.ts) — authors never import it; `agent/storage.ts`
34
+ * is rejected on v2.
35
+ */
36
+
37
+ import type {
38
+ StorageABTable,
39
+ StorageCasTable,
40
+ StorageConfig,
41
+ StorageEntry,
42
+ StorageEvalsTable,
43
+ } from "../storage.js";
44
+ import type { JsonValue, KvCasResult, KvVersionedEntry } from "../types.js";
45
+ import {
46
+ CURSOR_HOSTED_STORAGE,
47
+ type CursorHostedStorageOptions,
48
+ cursorHostedStorage,
49
+ storageRpc,
50
+ } from "./cursor-hosted.js";
51
+
52
+ const KV_V2_PREFIX = "/internal/agentsdk/kv";
53
+
54
+ /** Wire shape of the v2 `get` route. `null` ⇒ JSON `undefined`. */
55
+ export interface KvV2GetResponse {
56
+ found: boolean;
57
+ value: JsonValue | null;
58
+ version: string | null;
59
+ }
60
+
61
+ /** Wire shape of the v2 `put` route (all three write modes). */
62
+ export interface KvV2PutResponse {
63
+ ok: boolean;
64
+ /** New version token on an accepted write, else `null`. */
65
+ version: string | null;
66
+ /** Entry observed when a conditional write lost; `null` when absent. */
67
+ current: { value: JsonValue | null; version: string } | null;
68
+ }
69
+
70
+ /** Wire shape of the v2 `list` route. */
71
+ export interface KvV2ListResponse {
72
+ entries: Array<{
73
+ key: string;
74
+ /** Omitted when the request asked for keys only. */
75
+ value?: JsonValue | null;
76
+ version: string;
77
+ }>;
78
+ /** Last key of this page when more rows remain, else `null`. */
79
+ nextCursor: string | null;
80
+ }
81
+
82
+ type CursorHostedStorageV2Methods = Required<
83
+ Pick<StorageConfig, "put" | "get" | "delete" | "list">
84
+ > & {
85
+ readonly [CURSOR_HOSTED_STORAGE]: true;
86
+ cas: StorageCasTable;
87
+ evals: StorageEvalsTable;
88
+ abs: StorageABTable;
89
+ };
90
+
91
+ function toCasResult(response: KvV2PutResponse): KvCasResult {
92
+ if (response.ok) {
93
+ if (response.version === null) {
94
+ throw new Error(
95
+ "cursorHostedStorageV2: conditional write succeeded without a version token"
96
+ );
97
+ }
98
+ return { ok: true, version: response.version };
99
+ }
100
+ const current: KvVersionedEntry | undefined =
101
+ response.current === null
102
+ ? undefined
103
+ : {
104
+ value: response.current.value ?? null,
105
+ version: response.current.version,
106
+ };
107
+ return { ok: false, current };
108
+ }
109
+
110
+ /**
111
+ * Drain every page of a v2 `list` scan. The server pages by keyset (each
112
+ * `nextCursor` is the strictly-greatest key returned so far), so a cursor
113
+ * that fails to advance means a broken server — fail loudly rather than
114
+ * loop forever.
115
+ */
116
+ async function listAllPages(
117
+ options: CursorHostedStorageOptions,
118
+ body: { prefix: string; keysOnly?: boolean }
119
+ ): Promise<KvV2ListResponse["entries"]> {
120
+ const entries: KvV2ListResponse["entries"] = [];
121
+ let cursor: string | undefined;
122
+ for (;;) {
123
+ const page = await storageRpc<KvV2ListResponse>(
124
+ options,
125
+ `${KV_V2_PREFIX}/list`,
126
+ cursor === undefined ? body : { ...body, cursor }
127
+ );
128
+ entries.push(...page.entries);
129
+ if (page.nextCursor === null) {
130
+ return entries;
131
+ }
132
+ if (cursor !== undefined && page.nextCursor <= cursor) {
133
+ throw new Error(
134
+ `cursorHostedStorageV2: list("${body.prefix}") cursor did not advance`
135
+ );
136
+ }
137
+ cursor = page.nextCursor;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Architecture-v2 `defineStorage` methods (AgentSDK v2 KV proxy → factorydb
143
+ * `agentsdk_kv`). Platform-selected; spread into `defineStorage({...})` by
144
+ * framework-storage-selection.ts. No `listNewest`: v2 session records live
145
+ * on the framework file store, so the only consumer of write-time ordering
146
+ * never reaches this backend and the engine's `list` fallback covers the
147
+ * rest.
148
+ */
149
+ export function cursorHostedStorageV2(
150
+ options: CursorHostedStorageOptions = {}
151
+ ): CursorHostedStorageV2Methods {
152
+ // Eval runs and A/B samples stay on the v1 proxy's dedicated tables.
153
+ const v1 = cursorHostedStorage(options);
154
+ return {
155
+ [CURSOR_HOSTED_STORAGE]: true,
156
+ async put(key, value): Promise<void> {
157
+ await storageRpc(options, `${KV_V2_PREFIX}/put`, { key, value });
158
+ },
159
+ async get(key): Promise<JsonValue | undefined> {
160
+ const result = await storageRpc<KvV2GetResponse>(
161
+ options,
162
+ `${KV_V2_PREFIX}/get`,
163
+ { key }
164
+ );
165
+ if (!result.found) {
166
+ return undefined;
167
+ }
168
+ return result.value ?? undefined;
169
+ },
170
+ async delete(key): Promise<void> {
171
+ await storageRpc(options, `${KV_V2_PREFIX}/delete`, { key });
172
+ },
173
+ async list(prefix): Promise<StorageEntry[]> {
174
+ const entries = await listAllPages(options, { prefix });
175
+ return entries.map((entry) => ({
176
+ key: entry.key,
177
+ value: entry.value ?? null,
178
+ }));
179
+ },
180
+ cas: {
181
+ async getWithVersion(key): Promise<KvVersionedEntry | undefined> {
182
+ const result = await storageRpc<KvV2GetResponse>(
183
+ options,
184
+ `${KV_V2_PREFIX}/get`,
185
+ { key }
186
+ );
187
+ if (!result.found || result.version === null) {
188
+ return undefined;
189
+ }
190
+ return { value: result.value ?? null, version: result.version };
191
+ },
192
+ async putIfAbsent(key, value): Promise<KvCasResult> {
193
+ const result = await storageRpc<KvV2PutResponse>(
194
+ options,
195
+ `${KV_V2_PREFIX}/put`,
196
+ { key, value, ifAbsent: true }
197
+ );
198
+ return toCasResult(result);
199
+ },
200
+ async putIfVersion(key, value, expectedVersion): Promise<KvCasResult> {
201
+ const result = await storageRpc<KvV2PutResponse>(
202
+ options,
203
+ `${KV_V2_PREFIX}/put`,
204
+ { key, value, ifVersion: expectedVersion }
205
+ );
206
+ return toCasResult(result);
207
+ },
208
+ async listKeys(prefix): Promise<string[]> {
209
+ const entries = await listAllPages(options, {
210
+ prefix,
211
+ keysOnly: true,
212
+ });
213
+ return entries.map((entry) => entry.key);
214
+ },
215
+ },
216
+ evals: v1.evals,
217
+ abs: v1.abs,
218
+ };
219
+ }
@@ -207,7 +207,12 @@ function resolveBaseUrl(options: CursorHostedStorageOptions): string {
207
207
  return raw.endsWith("/") ? raw.slice(0, -1) : raw;
208
208
  }
209
209
 
210
- async function storageRpc<T>(
210
+ /**
211
+ * One authenticated POST to the control-plane proxy. Shared with the
212
+ * architecture-v2 backend (`cursor-hosted-v2.ts`), which speaks a different
213
+ * route family over the same transport and credential chain.
214
+ */
215
+ export async function storageRpc<T>(
211
216
  options: CursorHostedStorageOptions,
212
217
  path: string,
213
218
  body: Record<string, unknown>
package/src/types.ts CHANGED
@@ -2314,6 +2314,11 @@ export interface ChannelMeta {
2314
2314
  * by `info` so watched channels are auditable.
2315
2315
  */
2316
2316
  slackChannelPosts?: readonly string[];
2317
+ /**
2318
+ * Author-facing notices about deprecated options the pack still honored.
2319
+ * Discovery surfaces each one as a `validate` warning on the channel file.
2320
+ */
2321
+ deprecations?: readonly string[];
2317
2322
  }
2318
2323
 
2319
2324
  export interface ChannelConfig<TState = JsonValue> {