@cursor/july 0.1.104 → 0.1.107

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 (286) hide show
  1. package/dist/bin/agent-serve.js +1 -8
  2. package/dist/channels/bitbucket/types.d.ts +2 -4
  3. package/dist/channels/bitbucket/types.d.ts.map +1 -1
  4. package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
  5. package/dist/channels/deployments/deployments-channel.js +1 -0
  6. package/dist/channels/deployments/types.d.ts +7 -8
  7. package/dist/channels/deployments/types.d.ts.map +1 -1
  8. package/dist/channels/github/types.d.ts +2 -4
  9. package/dist/channels/github/types.d.ts.map +1 -1
  10. package/dist/channels/gitlab/types.d.ts +2 -5
  11. package/dist/channels/gitlab/types.d.ts.map +1 -1
  12. package/dist/channels/origin/types.d.ts +2 -3
  13. package/dist/channels/origin/types.d.ts.map +1 -1
  14. package/dist/channels/slack/defaults.d.ts.map +1 -1
  15. package/dist/channels/slack/defaults.js +3 -0
  16. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  17. package/dist/channels/slack/dispatch.js +1 -1
  18. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  19. package/dist/channels/slack/live-delivery.js +48 -11
  20. package/dist/channels/slack/types.d.ts +4 -3
  21. package/dist/channels/slack/types.d.ts.map +1 -1
  22. package/dist/docs/404.html +3 -3
  23. package/dist/docs/ab.html +6 -6
  24. package/dist/docs/assets/{app.DbMWUyGb.js → app.CtuckIiL.js} +1 -1
  25. package/dist/docs/assets/chunks/@localSearchIndexroot.DXXZxiMv.js +1 -0
  26. package/dist/docs/assets/chunks/{VPLocalSearchBox.DcNeTh9o.js → VPLocalSearchBox.Bkkhnu8K.js} +2 -2
  27. package/dist/docs/assets/chunks/{theme.DMjhY3gl.js → theme.DhpIe0Pa.js} +2 -2
  28. package/dist/docs/assets/guides_grokbot-agents.md.DVqdhBKb.js +9 -0
  29. package/dist/docs/assets/guides_grokbot-agents.md.DVqdhBKb.lean.js +1 -0
  30. package/dist/docs/assets/{guides_opentelemetry.md.COh9jFVg.js → guides_opentelemetry.md.SCRMskno.js} +3 -3
  31. package/dist/docs/assets/{guides_opentelemetry.md.COh9jFVg.lean.js → guides_opentelemetry.md.SCRMskno.lean.js} +1 -1
  32. package/dist/docs/assets/index.md.BW_6tOgR.js +5 -0
  33. package/dist/docs/assets/index.md.BW_6tOgR.lean.js +1 -0
  34. package/dist/docs/assets/{reference_channels.md.DBGcaB7m.js → reference_channels.md.D-qTqwcq.js} +2 -2
  35. package/dist/docs/assets/{reference_channels.md.DBGcaB7m.lean.js → reference_channels.md.D-qTqwcq.lean.js} +1 -1
  36. package/dist/docs/assets/{reference_cli.md.CJNc_xYK.js → reference_cli.md.Dm67hd2D.js} +3 -2
  37. package/dist/docs/assets/{reference_extensions.md.DykHW3qL.js → reference_extensions.md.CGmMLblt.js} +1 -1
  38. package/dist/docs/assets/{skills_otel.md.CqhobH3B.js → skills_otel.md.B5Ddv1xH.js} +1 -1
  39. package/dist/docs/assets/{style.BRuM8477.css → style.DCD_zyg3.css} +1 -1
  40. package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.js +3 -0
  41. package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.lean.js +1 -0
  42. package/dist/docs/building-with-agents.html +6 -6
  43. package/dist/docs/concepts.html +5 -5
  44. package/dist/docs/deployment.html +6 -6
  45. package/dist/docs/evals.html +6 -6
  46. package/dist/docs/guides/agent-to-agent.html +6 -6
  47. package/dist/docs/guides/cloud-agents.html +6 -6
  48. package/dist/docs/guides/convert-automation.html +6 -6
  49. package/dist/docs/guides/github.html +6 -6
  50. package/dist/docs/guides/grokbot-agents.html +35 -0
  51. package/dist/docs/guides/grokbot-agents.md +88 -0
  52. package/dist/docs/guides/human-in-the-loop.html +6 -6
  53. package/dist/docs/guides/mcp-oauth.html +6 -6
  54. package/dist/docs/guides/opentelemetry.html +8 -8
  55. package/dist/docs/guides/opentelemetry.md +3 -4
  56. package/dist/docs/guides/slack.html +6 -6
  57. package/dist/docs/guides/webhooks.html +6 -6
  58. package/dist/docs/hashmap.json +1 -1
  59. package/dist/docs/hillclimbing.html +6 -6
  60. package/dist/docs/index.html +8 -8
  61. package/dist/docs/index.md +6 -1
  62. package/dist/docs/llms-full.txt +178 -30
  63. package/dist/docs/llms.txt +2 -0
  64. package/dist/docs/quickstart.html +6 -6
  65. package/dist/docs/reference/agent-config.html +6 -6
  66. package/dist/docs/reference/artifacts.html +6 -6
  67. package/dist/docs/reference/channels.html +7 -7
  68. package/dist/docs/reference/channels.md +11 -19
  69. package/dist/docs/reference/cli.html +10 -9
  70. package/dist/docs/reference/cli.md +7 -3
  71. package/dist/docs/reference/connections.html +6 -6
  72. package/dist/docs/reference/extensions.html +7 -7
  73. package/dist/docs/reference/extensions.md +2 -0
  74. package/dist/docs/reference/hooks.html +6 -6
  75. package/dist/docs/reference/http-api.html +6 -6
  76. package/dist/docs/reference/instructions.html +6 -6
  77. package/dist/docs/reference/playground.html +5 -5
  78. package/dist/docs/reference/project-layout.html +6 -6
  79. package/dist/docs/reference/prompt.html +6 -6
  80. package/dist/docs/reference/result.html +6 -6
  81. package/dist/docs/reference/schedules.html +6 -6
  82. package/dist/docs/reference/sessions.html +5 -5
  83. package/dist/docs/reference/skills.html +6 -6
  84. package/dist/docs/reference/subagents.html +6 -6
  85. package/dist/docs/reference/tools.html +6 -6
  86. package/dist/docs/scaffolding-agents.html +5 -5
  87. package/dist/docs/skills/ab.html +6 -6
  88. package/dist/docs/skills/create-agent.html +6 -6
  89. package/dist/docs/skills/debug.html +5 -5
  90. package/dist/docs/skills/evals.html +6 -6
  91. package/dist/docs/skills/framework-map.html +5 -5
  92. package/dist/docs/skills/github.html +6 -6
  93. package/dist/docs/skills/hillclimb.html +6 -6
  94. package/dist/docs/skills/index.html +5 -5
  95. package/dist/docs/skills/mcp-auth.html +6 -6
  96. package/dist/docs/skills/otel.html +8 -8
  97. package/dist/docs/skills/otel.md +3 -3
  98. package/dist/docs/skills/setup-slack.html +6 -6
  99. package/dist/docs/storage.html +6 -6
  100. package/dist/docs/templates/agentic-owners.html +6 -6
  101. package/dist/docs/templates/agents-md.html +6 -6
  102. package/dist/docs/templates/code-wiki.html +6 -6
  103. package/dist/docs/templates/demo.html +6 -6
  104. package/dist/docs/templates/grokbot-agents.html +29 -0
  105. package/dist/docs/templates/grokbot-agents.md +48 -0
  106. package/dist/docs/templates/pr-autofixer.html +6 -6
  107. package/dist/docs/templates/security-help.html +6 -6
  108. package/dist/docs/templates/security-reviewer.html +6 -6
  109. package/dist/docs/templates/triage.html +6 -6
  110. package/dist/docs/troubleshooting.html +5 -5
  111. package/dist/files.d.ts +7 -2
  112. package/dist/files.d.ts.map +1 -1
  113. package/dist/files.js +7 -2
  114. package/dist/index.d.ts +4 -5
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +3 -4
  117. package/dist/internal/cli-deploy.d.ts.map +1 -1
  118. package/dist/internal/cli-deploy.js +23 -11
  119. package/dist/internal/cursor/backend-client.d.ts +25 -0
  120. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  121. package/dist/internal/cursor/backend-client.js +57 -2
  122. package/dist/internal/cursor-agent-template.d.ts +1 -1
  123. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  124. package/dist/internal/cursor-agent-template.js +1 -0
  125. package/dist/internal/deploy-client.d.ts +8 -0
  126. package/dist/internal/deploy-client.d.ts.map +1 -1
  127. package/dist/internal/deploy-client.js +14 -0
  128. package/dist/internal/deploy-manifest.d.ts +3 -0
  129. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  130. package/dist/internal/deploy-manifest.js +15 -12
  131. package/dist/internal/discovery/agent.d.ts.map +1 -1
  132. package/dist/internal/discovery/agent.js +1 -0
  133. package/dist/internal/discovery/info.d.ts.map +1 -1
  134. package/dist/internal/discovery/info.js +7 -3
  135. package/dist/internal/discovery/modules.d.ts +1 -1
  136. package/dist/internal/discovery/modules.d.ts.map +1 -1
  137. package/dist/internal/discovery/modules.js +1 -0
  138. package/dist/internal/discovery/project.d.ts.map +1 -1
  139. package/dist/internal/discovery/project.js +3 -0
  140. package/dist/internal/discovery/reminders.d.ts +7 -0
  141. package/dist/internal/discovery/reminders.d.ts.map +1 -0
  142. package/dist/internal/discovery/reminders.js +65 -0
  143. package/dist/internal/discovery/subagent.js +1 -0
  144. package/dist/internal/distribution.d.ts +5 -0
  145. package/dist/internal/distribution.d.ts.map +1 -1
  146. package/dist/internal/distribution.js +17 -0
  147. package/dist/internal/framework-file-storage.d.ts +3 -1
  148. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  149. package/dist/internal/framework-file-storage.js +3 -1
  150. package/dist/internal/framework-storage-selection.d.ts +14 -3
  151. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  152. package/dist/internal/framework-storage-selection.js +36 -6
  153. package/dist/internal/guest-network.d.ts.map +1 -1
  154. package/dist/internal/guest-network.js +2 -0
  155. package/dist/internal/hosted-delivery-protocol.d.ts +48 -0
  156. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  157. package/dist/internal/hosted-delivery-protocol.js +60 -0
  158. package/dist/internal/hosted-delivery.d.ts +17 -0
  159. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  160. package/dist/internal/hosted-delivery.js +112 -19
  161. package/dist/internal/hosted-managed-automation.d.ts.map +1 -1
  162. package/dist/internal/hosted-managed-automation.js +27 -2
  163. package/dist/internal/init-project.d.ts.map +1 -1
  164. package/dist/internal/init-project.js +4 -1
  165. package/dist/internal/local-control-plane.d.ts +18 -2
  166. package/dist/internal/local-control-plane.d.ts.map +1 -1
  167. package/dist/internal/local-control-plane.js +199 -17
  168. package/dist/internal/reminder-control-plane-protocol.d.ts +187 -0
  169. package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -0
  170. package/dist/internal/reminder-control-plane-protocol.js +244 -0
  171. package/dist/internal/reminder-runner.d.ts +48 -6
  172. package/dist/internal/reminder-runner.d.ts.map +1 -1
  173. package/dist/internal/reminder-runner.js +336 -48
  174. package/dist/internal/reminder-schedule.d.ts +5 -2
  175. package/dist/internal/reminder-schedule.d.ts.map +1 -1
  176. package/dist/internal/reminder-schedule.js +8 -6
  177. package/dist/internal/reminder-store.d.ts +24 -7
  178. package/dist/internal/reminder-store.d.ts.map +1 -1
  179. package/dist/internal/reminder-store.js +6 -5
  180. package/dist/internal/request-error-status.d.ts +2 -0
  181. package/dist/internal/request-error-status.d.ts.map +1 -1
  182. package/dist/internal/request-error-status.js +22 -3
  183. package/dist/internal/scm/pr-url.d.ts +40 -0
  184. package/dist/internal/scm/pr-url.d.ts.map +1 -1
  185. package/dist/internal/scm/pr-url.js +93 -14
  186. package/dist/internal/sdk-runner.d.ts +12 -0
  187. package/dist/internal/sdk-runner.d.ts.map +1 -1
  188. package/dist/internal/sdk-runner.js +18 -0
  189. package/dist/internal/server.d.ts.map +1 -1
  190. package/dist/internal/server.js +78 -30
  191. package/dist/internal/session-engine.d.ts +12 -0
  192. package/dist/internal/session-engine.d.ts.map +1 -1
  193. package/dist/internal/session-engine.js +137 -52
  194. package/dist/internal/store-mirror.d.ts +2 -2
  195. package/dist/internal/store-mirror.js +2 -2
  196. package/dist/internal/tenant-slack/relay.d.ts +2 -0
  197. package/dist/internal/tenant-slack/relay.d.ts.map +1 -1
  198. package/dist/internal/tenant-slack/relay.js +18 -8
  199. package/dist/internal/workspace-sync.d.ts +31 -6
  200. package/dist/internal/workspace-sync.d.ts.map +1 -1
  201. package/dist/internal/workspace-sync.js +67 -12
  202. package/dist/internal/workspace.d.ts +9 -0
  203. package/dist/internal/workspace.d.ts.map +1 -1
  204. package/dist/internal/workspace.js +16 -0
  205. package/dist/playground/assets/index-Bq2HpEQB.js +67 -0
  206. package/dist/playground/assets/index-CZKKNlmb.css +1 -0
  207. package/dist/playground/index.html +2 -2
  208. package/dist/reminders.d.ts +24 -5
  209. package/dist/reminders.d.ts.map +1 -1
  210. package/dist/reminders.js +28 -5
  211. package/dist/types.d.ts +98 -28
  212. package/dist/types.d.ts.map +1 -1
  213. package/docs/README.md +6 -1
  214. package/docs/guides/grokbot-agents.md +93 -0
  215. package/docs/guides/opentelemetry.md +3 -4
  216. package/docs/reference/channels.md +11 -19
  217. package/docs/reference/cli.md +7 -3
  218. package/docs/reference/extensions.md +2 -0
  219. package/docs/templates/grokbot-agents.md +53 -0
  220. package/package.json +12 -3
  221. package/skills/otel/SKILL.md +3 -3
  222. package/src/bin/agent-serve.ts +1 -9
  223. package/src/channels/bitbucket/types.ts +2 -4
  224. package/src/channels/deployments/deployments-channel.ts +1 -0
  225. package/src/channels/deployments/types.ts +7 -8
  226. package/src/channels/github/types.ts +2 -4
  227. package/src/channels/gitlab/types.ts +2 -5
  228. package/src/channels/origin/types.ts +2 -3
  229. package/src/channels/slack/defaults.ts +3 -0
  230. package/src/channels/slack/dispatch.ts +1 -0
  231. package/src/channels/slack/live-delivery.ts +53 -12
  232. package/src/channels/slack/types.ts +4 -3
  233. package/src/files.ts +9 -2
  234. package/src/index.ts +6 -3
  235. package/src/internal/cli-deploy.ts +30 -12
  236. package/src/internal/cursor/backend-client.ts +90 -2
  237. package/src/internal/cursor-agent-template.ts +1 -0
  238. package/src/internal/deploy-client.ts +16 -0
  239. package/src/internal/deploy-manifest.ts +16 -11
  240. package/src/internal/discovery/agent.ts +1 -0
  241. package/src/internal/discovery/info.ts +6 -0
  242. package/src/internal/discovery/modules.ts +2 -4
  243. package/src/internal/discovery/project.ts +3 -0
  244. package/src/internal/discovery/reminders.ts +65 -0
  245. package/src/internal/discovery/subagent.ts +1 -0
  246. package/src/internal/distribution.ts +20 -0
  247. package/src/internal/framework-file-storage.ts +3 -1
  248. package/src/internal/framework-storage-selection.ts +43 -6
  249. package/src/internal/guest-network.ts +3 -0
  250. package/src/internal/hosted-delivery-protocol.ts +96 -0
  251. package/src/internal/hosted-delivery.ts +207 -28
  252. package/src/internal/hosted-managed-automation.ts +49 -5
  253. package/src/internal/init-project.ts +4 -1
  254. package/src/internal/local-control-plane.ts +281 -22
  255. package/src/internal/reminder-control-plane-protocol.ts +499 -0
  256. package/src/internal/reminder-runner.ts +421 -48
  257. package/src/internal/reminder-schedule.ts +11 -6
  258. package/src/internal/reminder-store.ts +27 -7
  259. package/src/internal/request-error-status.ts +27 -3
  260. package/src/internal/scm/pr-url.ts +167 -20
  261. package/src/internal/sdk-runner.ts +19 -0
  262. package/src/internal/server.ts +85 -16
  263. package/src/internal/session-engine.ts +173 -56
  264. package/src/internal/store-mirror.ts +2 -2
  265. package/src/internal/tenant-slack/relay.ts +28 -4
  266. package/src/internal/workspace-sync.ts +84 -12
  267. package/src/internal/workspace.ts +20 -0
  268. package/src/reminders.ts +35 -4
  269. package/src/types.ts +104 -28
  270. package/templates/grokbot-agents/README.md +26 -0
  271. package/templates/grokbot-agents/agent/agent.ts +6 -0
  272. package/templates/grokbot-agents/agent/extensions/grokbot.ts +5 -0
  273. package/templates/grokbot-agents/agent/instructions.md +7 -0
  274. package/templates/grokbot-agents/evals/evals.config.ts +5 -0
  275. package/templates/grokbot-agents/evals/grokbot-agents.eval.ts +18 -0
  276. package/templates/grokbot-agents/init.json +18 -0
  277. package/templates/grokbot-agents/package.json +17 -0
  278. package/templates/grokbot-agents/tsconfig.json +12 -0
  279. package/dist/docs/assets/chunks/@localSearchIndexroot.Bqsulb9K.js +0 -1
  280. package/dist/docs/assets/index.md.D75GWhPl.js +0 -5
  281. package/dist/docs/assets/index.md.D75GWhPl.lean.js +0 -1
  282. package/dist/playground/assets/index-8YiozU89.js +0 -67
  283. package/dist/playground/assets/index-MbMxXg-y.css +0 -1
  284. /package/dist/docs/assets/{reference_cli.md.CJNc_xYK.lean.js → reference_cli.md.Dm67hd2D.lean.js} +0 -0
  285. /package/dist/docs/assets/{reference_extensions.md.DykHW3qL.lean.js → reference_extensions.md.CGmMLblt.lean.js} +0 -0
  286. /package/dist/docs/assets/{skills_otel.md.CqhobH3B.lean.js → skills_otel.md.B5Ddv1xH.lean.js} +0 -0
package/src/files.ts CHANGED
@@ -163,8 +163,10 @@ export const AGENT_SERVE_USER_STORE_KEY_PREFIX = "agent-serve";
163
163
  * Skills sit at store-root `skills/<name>/…` so exec-daemon's
164
164
  * `--agent-store-skills-dir` walk finds them the same way it finds user-store
165
165
  * skills. Workspace seeds sit at store-root `workspace/…` so the mount path
166
- * the first cloud prompt names stays short. Memory and artifacts stay under
167
- * {@link STORAGE_KEY_ROOT}.
166
+ * the first cloud prompt names stays short. Per-turn `workspaceFiles` sit at
167
+ * `sessions/<sessionId>/workspace/…` on that same shared mount (replace on
168
+ * later sends; wipe when a task session ends). Memory and artifacts stay
169
+ * under {@link STORAGE_KEY_ROOT}.
168
170
  */
169
171
  function createAgentStoreKeys(root: string) {
170
172
  return {
@@ -191,6 +193,11 @@ function createAgentStoreKeys(root: string) {
191
193
  /** Personal-key cloud agents: namespaced like {@link userSkillsPrefix}. */
192
194
  userWorkspacePrefix: (agent: string): string =>
193
195
  `${AGENT_SERVE_USER_STORE_KEY_PREFIX}/${agent}/workspace/`,
196
+ sessionWorkspacePrefix: (sessionId: string): string =>
197
+ `sessions/${sessionId}/workspace/`,
198
+ /** Personal-key cloud agents: namespaced like {@link sessionWorkspacePrefix}. */
199
+ userSessionWorkspacePrefix: (agent: string, sessionId: string): string =>
200
+ `${AGENT_SERVE_USER_STORE_KEY_PREFIX}/${agent}/sessions/${sessionId}/workspace/`,
194
201
  memoryDir: (agent: string): string => `${root}/${agent}/memory`,
195
202
  memoryJournal: (agent: string): string =>
196
203
  `${root}/${agent}/memory/journal.jsonl`,
package/src/index.ts CHANGED
@@ -139,7 +139,9 @@ export {
139
139
  TOOL_MCP_ENDPOINT_PATH,
140
140
  } from "./internal/mcp-endpoint.js";
141
141
  export {
142
+ REMINDER_ARGS_MAX_BYTES,
142
143
  ReminderValidationError,
144
+ rejectAnonymousReminderHandlers,
143
145
  UnknownReminderError,
144
146
  } from "./internal/reminder-runner.js";
145
147
  export type { AgentMount } from "./internal/server.js";
@@ -169,8 +171,10 @@ export { prompt } from "./prompt.js";
169
171
  export type {
170
172
  ReminderBusyPolicy,
171
173
  ReminderCreateInput,
174
+ ReminderDefinition,
172
175
  ReminderFireContext,
173
176
  ReminderFireResult,
177
+ ReminderHandlerConfig,
174
178
  ReminderHostApi,
175
179
  ReminderInfo,
176
180
  ReminderReschedule,
@@ -179,6 +183,7 @@ export type {
179
183
  ReminderTarget,
180
184
  ReminderUntilContext,
181
185
  } from "./reminders.js";
186
+ export { defineReminder } from "./reminders.js";
182
187
  export { defineResult } from "./result.js";
183
188
  export { defineSchedule } from "./schedules.js";
184
189
  export { defineSkill } from "./skills.js";
@@ -226,9 +231,7 @@ export {
226
231
 
227
232
  /**
228
233
  * Runtime config for an agent — authored at `agent/agent.ts` (the root
229
- * agent) or `agent/subagents/<id>/agent.ts` (a subagent). Set
230
- * `architecture: "v2"` to deploy onto the v2 control plane; omitted
231
- * channel continuation then inherits kind `/v2` defaults.
234
+ * agent) or `agent/subagents/<id>/agent.ts` (a subagent).
232
235
  */
233
236
  export function defineAgent(config: AgentConfig): AgentConfigDefinition {
234
237
  return brandDefinition("agent", config);
@@ -1570,14 +1570,26 @@ export async function cmdDelete(
1570
1570
  if (typeof ctx === "number") {
1571
1571
  return ctx;
1572
1572
  }
1573
- let accepted: DeleteAccepted;
1573
+ // Same dispatch as `stop`: v1 409s architecture-v2 slugs, so the v2
1574
+ // DELETE goes first. A v2 404 (missing slug, or an older backend)
1575
+ // falls through to the v1 agent-serve delete.
1576
+ let architecture: "v1" | "v2" = "v2";
1577
+ let accepted: DeleteAccepted | AgentkitStopAccepted;
1574
1578
  try {
1575
- accepted = await ctx.client.deleteDeployment({
1576
- teamId: ctx.teamId,
1577
- slug,
1578
- });
1579
+ accepted = await ctx.client.deleteAgentkit({ teamId: ctx.teamId, slug });
1579
1580
  } catch (error) {
1580
- return renderApiError(error, ctx.err);
1581
+ if (!(error instanceof DeployApiError) || error.status !== 404) {
1582
+ return renderApiError(error, ctx.err);
1583
+ }
1584
+ try {
1585
+ accepted = await ctx.client.deleteDeployment({
1586
+ teamId: ctx.teamId,
1587
+ slug,
1588
+ });
1589
+ architecture = "v1";
1590
+ } catch (v1Error) {
1591
+ return renderApiError(v1Error, ctx.err);
1592
+ }
1581
1593
  }
1582
1594
  if (ctx.noWait) {
1583
1595
  if (ctx.json) {
@@ -1588,7 +1600,11 @@ export async function cmdDelete(
1588
1600
  return 0;
1589
1601
  }
1590
1602
  try {
1591
- await pollUntilGone(ctx, slug);
1603
+ await pollUntilGone(ctx, slug, () =>
1604
+ architecture === "v2"
1605
+ ? ctx.client.getAgentkitDeploy({ teamId: ctx.teamId, slug })
1606
+ : ctx.client.getDeployment({ teamId: ctx.teamId, slug })
1607
+ );
1592
1608
  } catch (error) {
1593
1609
  return renderApiError(error, ctx.err);
1594
1610
  }
@@ -2103,7 +2119,12 @@ function transientDeployStatusWaitMs(
2103
2119
  */
2104
2120
  async function pollUntilGone(
2105
2121
  ctx: DeployCliContext,
2106
- slug: string
2122
+ slug: string,
2123
+ getDetail: () => Promise<{
2124
+ status: string;
2125
+ progress?: DeploymentProgress;
2126
+ statusMessage?: string | null;
2127
+ }>
2107
2128
  ): Promise<void> {
2108
2129
  const startedAt = Date.now();
2109
2130
  const tty = process.stderr.isTTY === true;
@@ -2126,10 +2147,7 @@ async function pollUntilGone(
2126
2147
 
2127
2148
  for (;;) {
2128
2149
  try {
2129
- const detail = await ctx.client.getDeployment({
2130
- teamId: ctx.teamId,
2131
- slug,
2132
- });
2150
+ const detail = await getDetail();
2133
2151
  report(deployProgressLabel(detail));
2134
2152
  } catch (error: unknown) {
2135
2153
  if (error instanceof DeployApiError && error.status === 404) {
@@ -82,6 +82,37 @@ const githubTokenResponseSchema: z.ZodType<CursorGithubToken> = z.object({
82
82
  expiresAt: z.string().datetime(),
83
83
  });
84
84
 
85
+ /** SCMs whose git fetches ride the backend's `/v0/scm-events/<provider>-git-proxy` routes. */
86
+ export type CursorScmCloneProvider = "gitlab" | "bitbucket";
87
+
88
+ /**
89
+ * Proxied clone target for a GitLab / Bitbucket repository. The backend
90
+ * never hands out the provider credential: git fetches go to `remoteUrl`
91
+ * on the backend with the caller's own Cursor API key as a bearer token,
92
+ * and the backend adds the tenant credential per request.
93
+ */
94
+ export interface CursorScmCloneTarget {
95
+ /** Absolute `<backend>/v0/scm-events/<provider>-git-proxy/<repo>.git`. */
96
+ remoteUrl: string;
97
+ /** Bearer credential git presents to the backend (the caller's API key). */
98
+ token: string;
99
+ /** ISO timestamp after which the caller re-resolves the target. */
100
+ expiresAt: string;
101
+ username: string;
102
+ authMode: "bearer";
103
+ }
104
+
105
+ const scmCloneTargetResponseSchema = z.object({
106
+ expiresAt: z.string().datetime(),
107
+ clone: z.object({
108
+ remotePath: z
109
+ .string()
110
+ .regex(/^\/v0\/scm-events\/[a-z]+-git-proxy\/.+\.git$/),
111
+ username: z.string().min(1),
112
+ authMode: z.literal("bearer"),
113
+ }),
114
+ });
115
+
85
116
  const mcpToolSchema = z.object({
86
117
  name: z.string(),
87
118
  providerIdentifier: z.string().optional(),
@@ -490,6 +521,62 @@ export class CursorBackendClient {
490
521
  return githubTokenResponseSchema.parse(parsed);
491
522
  }
492
523
 
524
+ /**
525
+ * Resolve the proxied clone target for a GitLab / Bitbucket repository
526
+ * (`owner/name`; GitLab `path_with_namespace`). Same authorization as the
527
+ * provider proxy this host already calls; the returned remote lives on
528
+ * the backend and takes this client's API key, never a provider token.
529
+ */
530
+ async getScmCloneTarget(
531
+ provider: CursorScmCloneProvider,
532
+ repo: string
533
+ ): Promise<CursorScmCloneTarget> {
534
+ const label = provider === "gitlab" ? "GitLab" : "Bitbucket";
535
+ let response: Response;
536
+ try {
537
+ response = await this.fetchImpl(
538
+ `${this.backendUrl}/v0/scm-events/${provider}-clone-target`,
539
+ {
540
+ method: "POST",
541
+ headers: {
542
+ "content-type": "application/json",
543
+ authorization: `Bearer ${this.currentApiKey()}`,
544
+ },
545
+ body: JSON.stringify({ repo }),
546
+ signal: AbortSignal.timeout(30_000),
547
+ }
548
+ );
549
+ } catch (error) {
550
+ throw new CursorBackendError(
551
+ `Cursor ${label} clone target request failed: ${describeError(error)}`
552
+ );
553
+ }
554
+ const text = await response.text();
555
+ if (!response.ok) {
556
+ throw new CursorBackendError(
557
+ describeGithubTokenHttpFailure(response.status, text, label),
558
+ response.status,
559
+ retryAfterMsFromResponse(response)
560
+ );
561
+ }
562
+ let parsed: unknown;
563
+ try {
564
+ parsed = JSON.parse(text) as unknown;
565
+ } catch {
566
+ throw new CursorBackendError(
567
+ `Cursor backend returned a non-JSON ${label} clone target response.`
568
+ );
569
+ }
570
+ const body = scmCloneTargetResponseSchema.parse(parsed);
571
+ return {
572
+ remoteUrl: `${this.backendUrl}${body.clone.remotePath}`,
573
+ token: this.currentApiKey(),
574
+ expiresAt: body.expiresAt,
575
+ username: body.clone.username,
576
+ authMode: body.clone.authMode,
577
+ };
578
+ }
579
+
493
580
  /**
494
581
  * One unary Connect-JSON call on `aiserver.v1.<service>` with the same
495
582
  * token exchange and 401 retry as the dashboard RPCs. Callers parse the
@@ -864,7 +951,8 @@ const MAX_GITHUB_TOKEN_RETRY_AFTER_MS = 60 * 60_000;
864
951
  */
865
952
  function describeGithubTokenHttpFailure(
866
953
  status: number,
867
- bodyText: string
954
+ bodyText: string,
955
+ label = "GitHub"
868
956
  ): string {
869
957
  const detail = githubTokenErrorFromBody(bodyText);
870
958
  if (status === 401) {
@@ -875,7 +963,7 @@ function describeGithubTokenHttpFailure(
875
963
  if (detail !== undefined) {
876
964
  return detail;
877
965
  }
878
- return `Cursor GitHub credential request failed (${status}).`;
966
+ return `Cursor ${label} credential request failed (${status}).`;
879
967
  }
880
968
 
881
969
  function githubTokenErrorFromBody(bodyText: string): string | undefined {
@@ -7,6 +7,7 @@ const TEMPLATE_NAMES = [
7
7
  "agents-md",
8
8
  "code-wiki",
9
9
  "demo",
10
+ "grokbot-agents",
10
11
  "pr-autofixer",
11
12
  "security-help",
12
13
  "security-reviewer",
@@ -675,6 +675,22 @@ export class AgentServeDeployClient {
675
675
  return agentkitStopAcceptedSchema.parse(raw);
676
676
  }
677
677
 
678
+ /**
679
+ * Delete a v2 deployment (`DELETE /internal/agentsdk/deployments/:slug`).
680
+ * 202 means accepted; poll {@link getAgentkitDeploy} until 404.
681
+ */
682
+ async deleteAgentkit(args: {
683
+ teamId: number;
684
+ slug: string;
685
+ }): Promise<AgentkitStopAccepted> {
686
+ const raw = await this.request({
687
+ method: "DELETE",
688
+ path: `/internal/agentsdk/deployments/${encodeURIComponent(args.slug)}?teamId=${args.teamId}`,
689
+ context: { verb: "delete", slug: args.slug },
690
+ });
691
+ return agentkitStopAcceptedSchema.parse(raw);
692
+ }
693
+
678
694
  async listDeployments(args: { teamId: number }): Promise<Deployment[]> {
679
695
  const raw = await this.request({
680
696
  method: "GET",
@@ -47,7 +47,7 @@ import {
47
47
  projectInfo,
48
48
  runtimeArchitectureCompatibilityError,
49
49
  } from "./discovery.js";
50
- import { packageVersion } from "./distribution.js";
50
+ import { packageGitSha, packageVersion } from "./distribution.js";
51
51
 
52
52
  export const DEPLOY_MANIFEST_VERSION: 1 = 1;
53
53
 
@@ -62,6 +62,10 @@ const agentDeployManifestV1Schema = z.object({
62
62
  manifestVersion: z.literal(DEPLOY_MANIFEST_VERSION),
63
63
  generatedAtMs: z.number().int().nonnegative(),
64
64
  cliVersion: z.string().min(1),
65
+ cliGitSha: z
66
+ .string()
67
+ .regex(/^[0-9a-f]{40,64}$/)
68
+ .optional(),
65
69
  declarations: z.object({
66
70
  egressDomains: z.array(z.string().min(1)).max(64),
67
71
  publicRoutePaths: z.array(z.string().min(1)).max(64),
@@ -115,6 +119,8 @@ export interface AgentDeployManifestV1 {
115
119
  generatedAtMs: number;
116
120
  /** `@cursor/july` version that produced the manifest. */
117
121
  cliVersion: string;
122
+ /** Git commit for a checkout-built `@cursor/july`; absent for npm builds. */
123
+ cliGitSha?: string;
118
124
  declarations: AgentDeployManifestDeclarations;
119
125
  /**
120
126
  * Full `projectInfo` payload (see `GET /v1/info`). Opaque to the wire
@@ -129,7 +135,7 @@ export interface AgentDeployManifestV1 {
129
135
  */
130
136
  export function buildAgentDeployManifest(
131
137
  project: AgentProject,
132
- options?: { nowMs?: number; cliVersion?: string }
138
+ options?: { nowMs?: number; cliVersion?: string; cliGitSha?: string }
133
139
  ): AgentDeployManifestV1 {
134
140
  const runtimeArchitectureError = runtimeArchitectureCompatibilityError(
135
141
  project.agent
@@ -167,20 +173,19 @@ export function buildAgentDeployManifest(
167
173
  manifestVersion: DEPLOY_MANIFEST_VERSION,
168
174
  generatedAtMs: options?.nowMs ?? Date.now(),
169
175
  cliVersion: options?.cliVersion ?? packageVersion(),
176
+ cliGitSha: options?.cliGitSha ?? packageGitSha(),
170
177
  declarations: {
171
178
  egressDomains: [...(project.agent.hosting?.egressDomains ?? [])],
172
179
  publicRoutePaths,
173
- // v2 ignores authored storage; deploy manifests describe
174
- // Cursor-hosted deployments, where framework-storage-selection.ts
175
- // injects the Cursor-hosted mirror.
180
+ // Deploy manifests describe Cursor-hosted deployments. When the agent
181
+ // authors no storage, framework-storage-selection.ts injects the
182
+ // platform Cursor-hosted mirror for both v1 and v2.
176
183
  frameworkStorage:
177
- project.agent.architecture === "v2"
184
+ project.storage === undefined
178
185
  ? "cursor-hosted"
179
- : project.storage === undefined
180
- ? "none"
181
- : isCursorHostedStorage(project.storage)
182
- ? "cursor-hosted"
183
- : "other",
186
+ : isCursorHostedStorage(project.storage)
187
+ ? "cursor-hosted"
188
+ : "other",
184
189
  ...(project.agent.architecture === undefined
185
190
  ? {}
186
191
  : { architecture: project.agent.architecture }),
@@ -372,6 +372,7 @@ export async function warnUnknownSlots(
372
372
  "subagents",
373
373
  "channels",
374
374
  "schedules",
375
+ "reminders",
375
376
  "hooks",
376
377
  "ab",
377
378
  "sandbox",
@@ -151,6 +151,12 @@ export function projectInfo(project: AgentProject): AgentProjectInfo {
151
151
  cron: schedule.cron,
152
152
  kind: schedule.kind,
153
153
  })),
154
+ reminders:
155
+ (project.reminders ?? []).length === 0
156
+ ? undefined
157
+ : (project.reminders ?? []).map((reminder) => ({
158
+ name: reminder.name,
159
+ })),
154
160
  hooks: project.hooks.map((hook) => hook.name),
155
161
  abs: project.abs.map((experiment) => experiment.name),
156
162
  ...(project.abConfig === undefined && project.abs.length === 0
@@ -9,10 +9,7 @@ import { type DiscoveryContext, displayPath, errorMessage } from "./context.js";
9
9
  import { isDirectory, isModuleFile, moduleStem, sortedEntries } from "./fs.js";
10
10
  import { validateName } from "./names.js";
11
11
 
12
- type ImportableKind = Exclude<
13
- DefinitionKind,
14
- "instructions" | "eval" | "reminder"
15
- >;
12
+ type ImportableKind = Exclude<DefinitionKind, "instructions" | "eval">;
16
13
 
17
14
  /** The module files of a slot directory whose filenames are valid names. */
18
15
  export async function moduleEntries(
@@ -104,6 +101,7 @@ const DEFINE_HELPER_NAME: Record<ImportableKind, string> = {
104
101
  channel: "defineChannel",
105
102
  "http-channel": "httpChannel",
106
103
  schedule: "defineSchedule",
104
+ reminder: "defineReminder",
107
105
  hook: "defineHook",
108
106
  ab: "defineAB",
109
107
  storage: "defineStorage",
@@ -31,6 +31,7 @@ import {
31
31
  } from "./fs.js";
32
32
  import { loadHooks } from "./hooks.js";
33
33
  import { NAME_PATTERN } from "./names.js";
34
+ import { loadReminders } from "./reminders.js";
34
35
  import { loadSchedules } from "./schedules.js";
35
36
  import {
36
37
  appendArtifactTool,
@@ -236,6 +237,7 @@ export async function loadAgentProject(
236
237
  }
237
238
  const schedules = await loadSchedules(ctx, join(agentDir, "schedules"));
238
239
  schedules.push(...projectSlots.schedules);
240
+ const reminders = await loadReminders(ctx, join(agentDir, "reminders"));
239
241
  const hooks = await loadHooks(ctx, join(agentDir, "hooks"));
240
242
  hooks.push(...projectSlots.hooks);
241
243
  const abs = await loadABs(ctx, agentDir);
@@ -291,6 +293,7 @@ export async function loadAgentProject(
291
293
  httpChannel: resolvedHttpChannel,
292
294
  channels,
293
295
  schedules,
296
+ reminders,
294
297
  hooks,
295
298
  abs,
296
299
  abConfig,
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `agent/reminders/*.ts`: named durable reminder fire handlers.
3
+ */
4
+
5
+ import { basename, extname, relative } from "node:path";
6
+ import type { DiscoveredReminder, ReminderDefinition } from "../../types.js";
7
+ import { getDefinitionKind } from "../brand.js";
8
+ import { type DiscoveryContext, displayPath } from "./context.js";
9
+ import { isDirectory, isModuleFile, toPosix, walkFiles } from "./fs.js";
10
+ import { importDefault } from "./modules.js";
11
+ import { NAME_PATTERN } from "./names.js";
12
+
13
+ export async function loadReminders(
14
+ ctx: DiscoveryContext,
15
+ remindersDir: string,
16
+ onDisable?: (name: string, path: string) => void
17
+ ): Promise<DiscoveredReminder[]> {
18
+ if (!(await isDirectory(remindersDir))) {
19
+ return [];
20
+ }
21
+ const reminders: DiscoveredReminder[] = [];
22
+ for (const filePath of await walkFiles(remindersDir)) {
23
+ const rel = toPosix(relative(remindersDir, filePath));
24
+ if (!isModuleFile(basename(filePath))) {
25
+ continue;
26
+ }
27
+ const name = rel.slice(0, -extname(rel).length);
28
+ if (!NAME_PATTERN.test(name) || name.includes("__")) {
29
+ ctx.diagnostics.push({
30
+ severity: "error",
31
+ path: displayPath(ctx, filePath),
32
+ message: name.includes("__")
33
+ ? `Reminder name "${name}" may not contain "__"; it is reserved for extension contributions (\`<ns>__<name>\`).`
34
+ : `Reminder name "${name}" must match ${NAME_PATTERN}.`,
35
+ });
36
+ continue;
37
+ }
38
+ const definition = await importDefault(
39
+ ctx,
40
+ filePath,
41
+ onDisable === undefined ? "reminder" : ["reminder", "disabled"]
42
+ );
43
+ if (definition === undefined) {
44
+ continue;
45
+ }
46
+ if (getDefinitionKind(definition) === "disabled") {
47
+ onDisable?.(name, filePath);
48
+ continue;
49
+ }
50
+ const reminder = definition as ReminderDefinition;
51
+ if (typeof reminder.run !== "function") {
52
+ ctx.diagnostics.push({
53
+ severity: "error",
54
+ path: displayPath(ctx, filePath),
55
+ message: "Reminder handlers require a `run` function.",
56
+ });
57
+ continue;
58
+ }
59
+ reminders.push({
60
+ name,
61
+ definition: reminder,
62
+ });
63
+ }
64
+ return reminders;
65
+ }
@@ -121,6 +121,7 @@ async function warnUnsupportedSubagentSlots(
121
121
  ["subagents", "nested subagents"],
122
122
  ["channels", "channels"],
123
123
  ["schedules", "schedules"],
124
+ ["reminders", "reminders"],
124
125
  ["hooks", "hooks"],
125
126
  ["sandbox", "sandbox files"],
126
127
  ] as const;
@@ -13,6 +13,8 @@ import { fileURLToPath, pathToFileURL } from "node:url";
13
13
 
14
14
  /** Published npm package name (pre-launch codename for Agent SDK). */
15
15
  export const PACKAGE_NAME = "@cursor/july";
16
+ const HOSTED_WORKTREE_SHA_FILENAME = ".cursor-hosted-worktree-sha";
17
+ const GIT_COMMIT_SHA_RE = /^[0-9a-f]{40,64}$/;
16
18
 
17
19
  /**
18
20
  * Bracketed product tag for stderr / ServeOptions.logger lines
@@ -59,6 +61,24 @@ export function packageVersion(): string {
59
61
  return packageManifest().version;
60
62
  }
61
63
 
64
+ /**
65
+ * Git commit of a checkout-built framework distribution. Published npm
66
+ * packages do not carry this marker and return undefined.
67
+ */
68
+ export function packageGitSha(): string | undefined {
69
+ try {
70
+ const sha = readFileSync(
71
+ join(packageRootDir(), "dist", HOSTED_WORKTREE_SHA_FILENAME),
72
+ "utf8"
73
+ )
74
+ .trim()
75
+ .toLowerCase();
76
+ return GIT_COMMIT_SHA_RE.test(sha) ? sha : undefined;
77
+ } catch {
78
+ return undefined;
79
+ }
80
+ }
81
+
62
82
  /** Facts `agent-sdk version` / `--version` print. */
63
83
  export interface CliVersionInfo {
64
84
  /** Published npm name (`@cursor/july`). */
@@ -9,7 +9,9 @@
9
9
  * - the **framework-level** store (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`)
10
10
  * holds engine-owned session state — session records, event transcripts,
11
11
  * hosted-execution run logs, the continuation index, and the SDK
12
- * conversation mirror — and is never exposed to authors or models.
12
+ * conversation mirror — and is never mounted into author code or models.
13
+ * The authenticated dashboard may read diagnostic families, but never the
14
+ * continuation index.
13
15
  *
14
16
  * This module puts framework session state on the framework store. The
15
17
  * {@link storageKeys} scheme was designed for exactly this: keys are a
@@ -13,7 +13,10 @@
13
13
  * That selection is a hosting-mode question, not an authoring question.
14
14
  * Architecture v2 moves it here: `agent/storage.ts` is rejected at
15
15
  * discovery (error diagnostic, so serve and deploy fail early), and the
16
- * platform picks the default
16
+ * platform picks the default. Architecture v1 with no authored file now
17
+ * uses the same hosted-vs-self-hosted split, so deleting `agent/storage.ts`
18
+ * (required to deploy the same tree onto v2) does not drop the Cursor-hosted
19
+ * session mirror on a still-v1 pod.
17
20
  *
18
21
  * - **Cursor-managed hosting** (the deployment-generation environment
19
22
  * variable is set, same signal that registers `GET /v1/manifest`):
@@ -33,8 +36,10 @@
33
36
  * - **Self-hosted**: no mirror. `--state-root` is the durable copy, which
34
37
  * is correct when the operator owns the disk.
35
38
  *
36
- * v1 keeps the authored definition (or nothing) so existing deployments are
37
- * untouched while they run.
39
+ * v1 still honors an authored `agent/storage.ts` when present. Hosted v1
40
+ * pods with no authored file get the Cursor-hosted lazy mirror (gated on
41
+ * `AGENT_SERVE_DEPLOYMENT_ID`, the same signal the previous authored sinks
42
+ * used). Self-hosted v1 with no authored file stays disk-only.
38
43
  *
39
44
  * Local disk is not part of this decision. `<stateRoot>/sessions/<id>/`
40
45
  * already holds `session.json` and `events.ndjson` unconditionally, through
@@ -44,6 +49,10 @@
44
49
 
45
50
  import { cursorHostedFiles } from "../files-backends/cursor-hosted.js";
46
51
  import { defineStorage, type StorageDefinition } from "../storage.js";
52
+ import {
53
+ AGENT_SERVE_DEPLOYMENT_ID_ENV_VAR,
54
+ cursorHostedStorage,
55
+ } from "../storage-backends/cursor-hosted.js";
47
56
  import { cursorHostedStorageV2 } from "../storage-backends/cursor-hosted-v2.js";
48
57
  import type { AgentArchitecture } from "../types.js";
49
58
  import { resolveApiKeySync } from "./cursor/credentials.js";
@@ -54,6 +63,13 @@ import {
54
63
  } from "./framework-file-storage.js";
55
64
  import { resolveAgentV2Hosting } from "./v2-hosting.js";
56
65
 
66
+ /**
67
+ * Hosted v2 event-chunk flush debounce. Matches the session view's live poll
68
+ * cadence; a streaming turn still caps each chunk at the coordinator's batch
69
+ * limit, so a long turn writes a few dozen chunks rather than one per event.
70
+ */
71
+ export const HOSTED_V2_EVENT_FLUSH_DEBOUNCE_MS = 2_000;
72
+
57
73
  export interface FrameworkStorageSelectionInput {
58
74
  /** `agent/storage.ts`, when the author wrote one (v1 only: discovery rejects it on v2). */
59
75
  readonly authored: StorageDefinition | undefined;
@@ -73,8 +89,21 @@ export function selectFrameworkStorageDefinition(
73
89
  input: FrameworkStorageSelectionInput
74
90
  ): StorageDefinition | undefined {
75
91
  if (input.architecture !== "v2") {
76
- // v1: the author decides, or there is no mirror.
77
- return input.authored;
92
+ if (input.authored !== undefined) {
93
+ return input.authored;
94
+ }
95
+ const env = input.env ?? process.env;
96
+ if ((env[AGENT_SERVE_DEPLOYMENT_ID_ENV_VAR] ?? "").trim() !== "") {
97
+ // Hosted v1 pod with no authored sink: keep the Cursor-hosted
98
+ // mirror (lazy restore) so agents can delete `agent/storage.ts`
99
+ // without losing durability while they still run architecture v1.
100
+ return defineStorage({
101
+ name: "cursor-hosted (lazy restore)",
102
+ policy: { restore: "off" },
103
+ ...cursorHostedStorage(),
104
+ });
105
+ }
106
+ return undefined;
78
107
  }
79
108
  if (input.authored !== undefined) {
80
109
  // Discovery rejects agent/storage.ts on v2 before an engine is built;
@@ -97,7 +126,15 @@ export function selectFrameworkStorageDefinition(
97
126
  // backend it is per-key HTTP round trips before the listener even
98
127
  // comes up). Follow-ups restore lazily by continuation or session id;
99
128
  // GET /v1/sessions lists from the sink either way.
100
- const policy = { restore: "off" } as const;
129
+ //
130
+ // Events flush on a quiet-period debounce rather than only at turn end so
131
+ // the read-only session view and dashboard trace (which have no resident
132
+ // engine to ask) see steps mid-turn. The turn-end record still lands
133
+ // before the execution reply: drainSessionDurability forces the flush.
134
+ const policy = {
135
+ restore: "off",
136
+ debounceMs: HOSTED_V2_EVENT_FLUSH_DEBOUNCE_MS,
137
+ } as const;
101
138
  // Full chain (env → bind file → stored login): frozen engines listen
102
139
  // unsigned and bind store ids + CURSOR_API_KEY at task time, after this
103
140
  // definition is constructed.
@@ -19,6 +19,8 @@
19
19
  * with that message instead of throwing.
20
20
  */
21
21
 
22
+ import { HOSTED_GUEST_RETRY_TRANSIENT } from "./hosted-delivery-protocol.js";
23
+
22
24
  export const GUEST_NETWORK_UNAVAILABLE = "guest_network_unavailable";
23
25
  export const GUEST_CONNECT_STALLED = "guest_connect_stalled";
24
26
 
@@ -369,6 +371,7 @@ export async function guestNetworkReadinessResponse(
369
371
  JSON.stringify({
370
372
  ok: false,
371
373
  error: GUEST_NETWORK_UNAVAILABLE,
374
+ retry: HOSTED_GUEST_RETRY_TRANSIENT,
372
375
  message: error.message,
373
376
  waitMs: error.waitMs,
374
377
  probeAttempts: error.probeAttempts,