@cursor/july 0.1.1 → 0.1.3

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 (298) hide show
  1. package/AGENTS.md +40 -7
  2. package/README.md +33 -24
  3. package/dist/bin/agent-serve.d.ts +3 -1
  4. package/dist/bin/agent-serve.d.ts.map +1 -1
  5. package/dist/bin/agent-serve.js +466 -140
  6. package/dist/channels/github/api.d.ts.map +1 -1
  7. package/dist/channels/github/api.js +31 -14
  8. package/dist/channels/github/cursor-account.d.ts +43 -0
  9. package/dist/channels/github/cursor-account.d.ts.map +1 -0
  10. package/dist/channels/github/cursor-account.js +95 -0
  11. package/dist/channels/github/github-channel.d.ts.map +1 -1
  12. package/dist/channels/github/github-channel.js +46 -9
  13. package/dist/channels/github/index.d.ts +2 -2
  14. package/dist/channels/github/index.js +2 -2
  15. package/dist/channels/github/types.d.ts +17 -0
  16. package/dist/channels/github/types.d.ts.map +1 -1
  17. package/dist/channels/slack/slack-channel.d.ts +8 -2
  18. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  19. package/dist/channels/slack/slack-channel.js +8 -0
  20. package/dist/channels/slack/types.d.ts +24 -3
  21. package/dist/channels/slack/types.d.ts.map +1 -1
  22. package/dist/channels/slack/types.js +15 -1
  23. package/dist/docs/404.html +2 -2
  24. package/dist/docs/ab.html +8 -8
  25. package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
  26. package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
  27. package/dist/docs/assets/{app.DqfFEmJd.js → app.BR0RbIdx.js} +1 -1
  28. package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
  29. package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
  30. package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.2Kg8jIp_.js} +2 -2
  31. package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
  32. package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
  33. package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
  34. package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
  35. package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
  36. package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
  37. package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
  38. package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
  39. package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
  40. package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
  41. package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
  42. package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
  43. package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
  44. package/dist/docs/assets/quickstart.md.BU6Iwi_9.js +204 -0
  45. package/dist/docs/assets/quickstart.md.BU6Iwi_9.lean.js +1 -0
  46. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
  47. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
  48. package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
  49. package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
  50. package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
  51. package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
  52. package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
  53. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
  54. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
  55. package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
  56. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
  57. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
  58. package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
  59. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
  60. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
  61. package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
  62. package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
  63. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
  64. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
  65. package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
  66. package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
  67. package/dist/docs/building-with-agents.html +4 -4
  68. package/dist/docs/concepts.html +4 -4
  69. package/dist/docs/deployment.html +7 -7
  70. package/dist/docs/evals.html +7 -7
  71. package/dist/docs/guides/agent-to-agent.html +6 -6
  72. package/dist/docs/guides/cloud-runtime.html +5 -5
  73. package/dist/docs/guides/github.html +14 -7
  74. package/dist/docs/guides/human-in-the-loop.html +6 -6
  75. package/dist/docs/guides/slack.html +8 -8
  76. package/dist/docs/guides/webhooks.html +6 -6
  77. package/dist/docs/hashmap.json +1 -1
  78. package/dist/docs/hillclimbing.html +5 -5
  79. package/dist/docs/index.html +7 -7
  80. package/dist/docs/quickstart.html +195 -26
  81. package/dist/docs/reference/agent-config.html +7 -7
  82. package/dist/docs/reference/channels.html +8 -8
  83. package/dist/docs/reference/cli.html +14 -9
  84. package/dist/docs/reference/connections.html +5 -5
  85. package/dist/docs/reference/hooks.html +5 -5
  86. package/dist/docs/reference/http-api.html +6 -6
  87. package/dist/docs/reference/instructions.html +13 -11
  88. package/dist/docs/reference/playground.html +4 -4
  89. package/dist/docs/reference/project-layout.html +4 -4
  90. package/dist/docs/reference/schedules.html +7 -7
  91. package/dist/docs/reference/sessions.html +4 -4
  92. package/dist/docs/reference/skills.html +6 -6
  93. package/dist/docs/reference/subagents.html +6 -6
  94. package/dist/docs/reference/tools.html +7 -7
  95. package/dist/docs/scaffolding-agents.html +5 -5
  96. package/dist/docs/storage.html +41 -0
  97. package/dist/docs/troubleshooting.html +4 -4
  98. package/dist/index.d.ts +2 -0
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +1 -0
  101. package/dist/internal/chat-client.d.ts +29 -3
  102. package/dist/internal/chat-client.d.ts.map +1 -1
  103. package/dist/internal/chat-client.js +180 -27
  104. package/dist/internal/cli-ax.d.ts +75 -2
  105. package/dist/internal/cli-ax.d.ts.map +1 -1
  106. package/dist/internal/cli-ax.js +600 -52
  107. package/dist/internal/cli-cursor.d.ts.map +1 -1
  108. package/dist/internal/cli-cursor.js +8 -36
  109. package/dist/internal/cli-deploy.d.ts +108 -0
  110. package/dist/internal/cli-deploy.d.ts.map +1 -0
  111. package/dist/internal/cli-deploy.js +1009 -0
  112. package/dist/internal/cursor/backend-client.d.ts +10 -1
  113. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  114. package/dist/internal/cursor/backend-client.js +79 -1
  115. package/dist/internal/cursor/credentials.d.ts +9 -0
  116. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  117. package/dist/internal/cursor/credentials.js +12 -0
  118. package/dist/internal/cursor/github-credentials.d.ts +44 -0
  119. package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
  120. package/dist/internal/cursor/github-credentials.js +195 -0
  121. package/dist/internal/deploy-client.d.ts +184 -0
  122. package/dist/internal/deploy-client.d.ts.map +1 -0
  123. package/dist/internal/deploy-client.js +395 -0
  124. package/dist/internal/deploy-source.d.ts +35 -0
  125. package/dist/internal/deploy-source.d.ts.map +1 -0
  126. package/dist/internal/deploy-source.js +118 -0
  127. package/dist/internal/discovery.d.ts +11 -0
  128. package/dist/internal/discovery.d.ts.map +1 -1
  129. package/dist/internal/discovery.js +116 -19
  130. package/dist/internal/distribution.d.ts.map +1 -1
  131. package/dist/internal/distribution.js +1 -0
  132. package/dist/internal/eval-run-store.d.ts +22 -3
  133. package/dist/internal/eval-run-store.d.ts.map +1 -1
  134. package/dist/internal/eval-run-store.js +39 -20
  135. package/dist/internal/eval-runner.d.ts +2 -0
  136. package/dist/internal/eval-runner.d.ts.map +1 -1
  137. package/dist/internal/eval-runner.js +2 -0
  138. package/dist/internal/event-mapper.d.ts +54 -1
  139. package/dist/internal/event-mapper.d.ts.map +1 -1
  140. package/dist/internal/event-mapper.js +151 -41
  141. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
  142. package/dist/internal/handleAgentServeTrigger.js +10 -12
  143. package/dist/internal/host-platforms.d.ts +7 -2
  144. package/dist/internal/host-platforms.d.ts.map +1 -1
  145. package/dist/internal/host-platforms.js +15 -10
  146. package/dist/internal/hosting.d.ts +37 -0
  147. package/dist/internal/hosting.d.ts.map +1 -0
  148. package/dist/internal/hosting.js +67 -0
  149. package/dist/internal/init-project.d.ts +88 -1
  150. package/dist/internal/init-project.d.ts.map +1 -1
  151. package/dist/internal/init-project.js +221 -31
  152. package/dist/internal/install-cursor-skills.d.ts +64 -0
  153. package/dist/internal/install-cursor-skills.d.ts.map +1 -0
  154. package/dist/internal/install-cursor-skills.js +274 -0
  155. package/dist/internal/logs-client.d.ts +60 -0
  156. package/dist/internal/logs-client.d.ts.map +1 -0
  157. package/dist/internal/logs-client.js +311 -0
  158. package/dist/internal/open-browser.d.ts +5 -0
  159. package/dist/internal/open-browser.d.ts.map +1 -0
  160. package/dist/internal/open-browser.js +34 -0
  161. package/dist/internal/playground/toolchain.d.ts.map +1 -1
  162. package/dist/internal/playground/toolchain.js +16 -11
  163. package/dist/internal/playground-proxy.d.ts +69 -0
  164. package/dist/internal/playground-proxy.d.ts.map +1 -0
  165. package/dist/internal/playground-proxy.js +468 -0
  166. package/dist/internal/prompt-context.d.ts +35 -0
  167. package/dist/internal/prompt-context.d.ts.map +1 -0
  168. package/dist/internal/prompt-context.js +71 -0
  169. package/dist/internal/reminder-runner.d.ts +7 -0
  170. package/dist/internal/reminder-runner.d.ts.map +1 -1
  171. package/dist/internal/reminder-runner.js +50 -6
  172. package/dist/internal/reminder-store.d.ts +2 -0
  173. package/dist/internal/reminder-store.d.ts.map +1 -1
  174. package/dist/internal/reminder-store.js +18 -0
  175. package/dist/internal/request-headers.d.ts +11 -0
  176. package/dist/internal/request-headers.d.ts.map +1 -0
  177. package/dist/internal/request-headers.js +14 -0
  178. package/dist/internal/resolve-prod-target.d.ts +42 -0
  179. package/dist/internal/resolve-prod-target.d.ts.map +1 -0
  180. package/dist/internal/resolve-prod-target.js +111 -0
  181. package/dist/internal/run-client.d.ts +2 -2
  182. package/dist/internal/run-client.d.ts.map +1 -1
  183. package/dist/internal/run-client.js +38 -23
  184. package/dist/internal/server.d.ts.map +1 -1
  185. package/dist/internal/server.js +182 -45
  186. package/dist/internal/session-engine.d.ts +50 -1
  187. package/dist/internal/session-engine.d.ts.map +1 -1
  188. package/dist/internal/session-engine.js +267 -23
  189. package/dist/internal/sessions-client.d.ts +21 -0
  190. package/dist/internal/sessions-client.d.ts.map +1 -0
  191. package/dist/internal/sessions-client.js +168 -0
  192. package/dist/internal/storage-coordinator.d.ts +139 -0
  193. package/dist/internal/storage-coordinator.d.ts.map +1 -0
  194. package/dist/internal/storage-coordinator.js +499 -0
  195. package/dist/internal/stream-progress.d.ts.map +1 -1
  196. package/dist/internal/stream-progress.js +31 -3
  197. package/dist/internal/terminal-style.d.ts +22 -0
  198. package/dist/internal/terminal-style.d.ts.map +1 -0
  199. package/dist/internal/terminal-style.js +49 -0
  200. package/dist/internal/trajectory.d.ts +10 -5
  201. package/dist/internal/trajectory.d.ts.map +1 -1
  202. package/dist/internal/trajectory.js +82 -10
  203. package/dist/internal/workspace.d.ts +11 -0
  204. package/dist/internal/workspace.d.ts.map +1 -1
  205. package/dist/internal/workspace.js +38 -4
  206. package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
  207. package/dist/playground/assets/index-D-vo2lV_.css +1 -0
  208. package/dist/playground/assets/index-x60b9q2j.js +312 -0
  209. package/dist/playground/index.html +2 -2
  210. package/dist/storage.d.ts +204 -0
  211. package/dist/storage.d.ts.map +1 -0
  212. package/dist/storage.js +153 -0
  213. package/dist/types.d.ts +70 -4
  214. package/dist/types.d.ts.map +1 -1
  215. package/docs/README.md +3 -2
  216. package/docs/guides/github.md +43 -8
  217. package/docs/guides/slack.md +1 -1
  218. package/docs/quickstart.md +350 -57
  219. package/docs/reference/cli.md +51 -3
  220. package/docs/reference/instructions.md +8 -6
  221. package/docs/scaffolding-agents.md +1 -1
  222. package/docs/storage.md +98 -0
  223. package/package.json +10 -1
  224. package/skills/ab/SKILL.md +8 -8
  225. package/skills/create-agent/SKILL.md +28 -22
  226. package/skills/debug/SKILL.md +11 -11
  227. package/skills/evals/SKILL.md +16 -16
  228. package/skills/framework-map/SKILL.md +6 -6
  229. package/skills/github/SKILL.md +22 -14
  230. package/skills/hillclimb/SKILL.md +10 -10
  231. package/skills/setup-slack/SKILL.md +13 -13
  232. package/src/bin/agent-serve.ts +552 -179
  233. package/src/channels/github/api.ts +42 -23
  234. package/src/channels/github/cursor-account.ts +165 -0
  235. package/src/channels/github/github-channel.ts +66 -6
  236. package/src/channels/github/index.ts +2 -2
  237. package/src/channels/github/types.ts +19 -0
  238. package/src/channels/slack/slack-channel.ts +17 -3
  239. package/src/channels/slack/types.ts +44 -3
  240. package/src/index.ts +13 -0
  241. package/src/internal/chat-client.ts +252 -37
  242. package/src/internal/cli-ax.ts +722 -72
  243. package/src/internal/cli-cursor.ts +14 -42
  244. package/src/internal/cli-deploy.ts +1319 -0
  245. package/src/internal/cursor/backend-client.ts +103 -1
  246. package/src/internal/cursor/credentials.ts +14 -0
  247. package/src/internal/cursor/github-credentials.ts +248 -0
  248. package/src/internal/deploy-client.ts +632 -0
  249. package/src/internal/deploy-source.ts +133 -0
  250. package/src/internal/discovery.ts +141 -17
  251. package/src/internal/distribution.ts +1 -0
  252. package/src/internal/eval-run-store.ts +50 -20
  253. package/src/internal/eval-runner.ts +5 -0
  254. package/src/internal/event-mapper.ts +222 -42
  255. package/src/internal/handleAgentServeTrigger.ts +10 -12
  256. package/src/internal/host-platforms.ts +28 -11
  257. package/src/internal/hosting.ts +77 -0
  258. package/src/internal/init-project.ts +333 -51
  259. package/src/internal/install-cursor-skills.ts +327 -0
  260. package/src/internal/logs-client.ts +442 -0
  261. package/src/internal/open-browser.ts +41 -0
  262. package/src/internal/playground/toolchain.ts +15 -13
  263. package/src/internal/playground-proxy.ts +576 -0
  264. package/src/internal/prompt-context.ts +95 -0
  265. package/src/internal/reminder-runner.ts +50 -6
  266. package/src/internal/reminder-store.ts +21 -0
  267. package/src/internal/request-headers.ts +23 -0
  268. package/src/internal/resolve-prod-target.ts +150 -0
  269. package/src/internal/run-client.ts +39 -36
  270. package/src/internal/server.ts +223 -28
  271. package/src/internal/session-engine.ts +307 -10
  272. package/src/internal/sessions-client.ts +182 -0
  273. package/src/internal/storage-coordinator.ts +615 -0
  274. package/src/internal/stream-progress.ts +36 -2
  275. package/src/internal/terminal-style.ts +74 -0
  276. package/src/internal/trajectory.ts +91 -13
  277. package/src/internal/workspace.ts +42 -4
  278. package/src/storage.ts +325 -0
  279. package/src/types.ts +82 -8
  280. package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
  281. package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
  282. package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
  283. package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
  284. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
  285. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
  286. package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
  287. package/dist/playground/assets/index-1K-hG-7p.css +0 -1
  288. package/dist/playground/assets/index-FlWjhg3x.js +0 -79
  289. /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
  290. /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
  291. /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
  292. /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
  293. /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
  294. /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
  295. /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
  296. /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
  297. /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
  298. /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
@@ -26,8 +26,8 @@ var __rest = (this && this.__rest) || function (s, e) {
26
26
  }
27
27
  return t;
28
28
  };
29
- import { mkdir, rm } from "node:fs/promises";
30
- import { join } from "node:path";
29
+ import { mkdir, rm, writeFile } from "node:fs/promises";
30
+ import { dirname, join } from "node:path";
31
31
  import { mergeABInstructions, resolveABMaxPlaygroundSessions, resolveABSplit, } from "../ab.js";
32
32
  import { slackThreadPermalink } from "../channels/slack/links.js";
33
33
  import { DIRECT_TOOL_CALL_CHANNEL_ID, isSymbolicConnectionTransport, } from "../types.js";
@@ -37,18 +37,21 @@ import { buildABSnapshot } from "./ab-snapshot.js";
37
37
  import { ApprovalGate } from "./approval-gate.js";
38
38
  import { samePrincipal } from "./auth.js";
39
39
  import { mergeCloudOptions, resolveSessionRuntime } from "./cloud-merge.js";
40
+ import { isDevMode } from "./dev-mode.js";
40
41
  import { EventLogStore } from "./event-log.js";
41
42
  import { TurnEventMapper } from "./event-mapper.js";
42
43
  import { createHostPlatforms } from "./host-platforms.js";
43
44
  import { formatContinuationToken, newContinuationKey, newSessionId, newToolCallId, } from "./ids.js";
44
45
  import { validateToolInput } from "./json-schema.js";
45
46
  import { McpHost } from "./mcp-host.js";
47
+ import { buildIdentitySection, buildSessionContextBlock, SCHEDULE_CHANNEL_PREFIX, } from "./prompt-context.js";
46
48
  import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
47
49
  import { SessionStore } from "./session-store.js";
50
+ import { StorageCoordinator } from "./storage-coordinator.js";
48
51
  import { normalizeToolResult, toolCallErrorMessage } from "./tool-result.js";
49
52
  import { buildAgentToolsCatalog, materializeWorkspace, writeWorkspaceFiles, } from "./workspace.js";
50
53
  export const HTTP_CHANNEL_ID = "http";
51
- export const SCHEDULE_CHANNEL_PREFIX = "schedule:";
54
+ export { SCHEDULE_CHANNEL_PREFIX } from "./prompt-context.js";
52
55
  export class SessionBusyError extends Error {
53
56
  constructor(sessionId) {
54
57
  super(`Session ${sessionId} already has a running turn; wait for session.waiting before sending a follow-up`);
@@ -106,8 +109,10 @@ export class ApprovalInterruptedError extends Error {
106
109
  }
107
110
  export class SessionEngine {
108
111
  constructor(options) {
109
- var _a;
110
- var _b;
112
+ var _a, _b;
113
+ var _c, _d, _e;
114
+ /** In-flight lazy restores, deduped per channel + continuation key. */
115
+ this.restoreInFlight = new Map();
111
116
  this.channelsById = new Map();
112
117
  /** Sessions with a turn being admitted (before the run promise exists). */
113
118
  this.pendingTurns = new Set();
@@ -126,17 +131,29 @@ export class SessionEngine {
126
131
  this.project = options.project;
127
132
  this.stateRoot = options.stateRoot;
128
133
  this.runner = options.runner;
129
- this.logger = (_b = options.logger) !== null && _b !== void 0 ? _b : (() => { });
134
+ this.logger = (_c = options.logger) !== null && _c !== void 0 ? _c : (() => { });
130
135
  this.sessions = new SessionStore(join(options.stateRoot, "sessions"));
131
136
  this.logs = new EventLogStore((sessionId) => this.sessions.eventFilePath(sessionId), (sessionId, error) => this.logger(`[agent-serve] failed to persist events for ${sessionId}: ${describeError(error)}`));
132
- this.abCollector = new ABCollector(options.project.abs, this.logger, (sessionId) => __awaiter(this, void 0, void 0, function* () { return (yield this.logs.get(sessionId)).snapshot(0); }), Object.assign({ projectRoot: options.project.rootDir }, (((_a = options.project.abConfig) === null || _a === void 0 ? void 0 : _a.persistSamples) === undefined
133
- ? {}
134
- : { persistSamples: options.project.abConfig.persistSamples })));
137
+ this.storage =
138
+ options.project.storage === undefined
139
+ ? undefined
140
+ : new StorageCoordinator({
141
+ definition: options.project.storage,
142
+ agentName: options.project.name,
143
+ projectRoot: options.project.rootDir,
144
+ logger: this.logger,
145
+ });
146
+ // Domain-specific hooks win; the defineStorage sink is the fallback.
147
+ const persistSamples = (_d = (_a = options.project.abConfig) === null || _a === void 0 ? void 0 : _a.persistSamples) !== null && _d !== void 0 ? _d : (_b = this.storage) === null || _b === void 0 ? void 0 : _b.asABSamplePersistence();
148
+ this.abCollector = new ABCollector(options.project.abs, this.logger, (sessionId) => __awaiter(this, void 0, void 0, function* () { return (yield this.logs.get(sessionId)).snapshot(0); }), {
149
+ projectRoot: options.project.rootDir,
150
+ persistSamples,
151
+ });
135
152
  // Peer and Cursor-account transports are symbolic until the serve host
136
153
  // resolves them; the host-side MCP registry starts with the concrete
137
154
  // connections and gains the rest via setResolvedConnections.
138
155
  this.mcpHost = new McpHost(options.project.agent.connections.filter((connection) => !isSymbolicConnectionTransport(connection.transport)));
139
- this.platforms = createHostPlatforms();
156
+ this.platforms = (_e = options.platforms) !== null && _e !== void 0 ? _e : createHostPlatforms();
140
157
  for (const channel of options.project.channels) {
141
158
  this.channelsById.set(channel.id, channel.definition);
142
159
  }
@@ -181,11 +198,17 @@ export class SessionEngine {
181
198
  */
182
199
  send(channelId_1, message_1) {
183
200
  return __awaiter(this, arguments, void 0, function* (channelId, message, options = {}) {
184
- var _a, _b, _c;
185
- const auth = (_a = options.auth) !== null && _a !== void 0 ? _a : null;
186
- const existing = options.continuationToken === undefined
201
+ var _a;
202
+ var _b, _c, _d;
203
+ const auth = (_b = options.auth) !== null && _b !== void 0 ? _b : null;
204
+ let existing = options.continuationToken === undefined
187
205
  ? undefined
188
206
  : yield this.sessions.findByContinuation(channelId, options.continuationToken);
207
+ if (existing === undefined && options.continuationToken !== undefined) {
208
+ // Local miss: the session may live only in the storage sink (it
209
+ // fell outside the startup restore window, or restore is lazy-only).
210
+ existing = yield this.restoreSessionByContinuation(channelId, options.continuationToken);
211
+ }
189
212
  if (existing !== undefined) {
190
213
  if (!samePrincipal(existing.auth, auth)) {
191
214
  throw new SessionAuthError(existing.sessionId);
@@ -209,9 +232,9 @@ export class SessionEngine {
209
232
  let record = {
210
233
  sessionId: newSessionId(),
211
234
  channelId,
212
- mode: (_b = options.mode) !== null && _b !== void 0 ? _b : "chat",
235
+ mode: (_c = options.mode) !== null && _c !== void 0 ? _c : "chat",
213
236
  purpose,
214
- continuationKey: (_c = options.continuationToken) !== null && _c !== void 0 ? _c : newContinuationKey(),
237
+ continuationKey: (_d = options.continuationToken) !== null && _d !== void 0 ? _d : newContinuationKey(),
215
238
  auth,
216
239
  title: options.title,
217
240
  channelState,
@@ -224,6 +247,7 @@ export class SessionEngine {
224
247
  updatedAt: now,
225
248
  };
226
249
  yield this.sessions.save(record);
250
+ (_a = this.storage) === null || _a === void 0 ? void 0 : _a.sessionRecord(record);
227
251
  yield this.appendEvent(record.sessionId, {
228
252
  type: "session.started",
229
253
  data: { channelId },
@@ -515,7 +539,10 @@ export class SessionEngine {
515
539
  // Yield so the HTTP NDJSON writer can flush tool start/result
516
540
  // events while sibling parallel tools are still executing.
517
541
  if (update.type === "tool-call-started" ||
518
- update.type === "tool-call-completed") {
542
+ update.type === "tool-call-completed" ||
543
+ // Nested subagent progress (newer SDKs); string check keeps
544
+ // typecheck green against older published `@cursor/sdk` pins.
545
+ update.type === "tool-call-delta") {
519
546
  yield yieldEventLoop();
520
547
  }
521
548
  }), signal);
@@ -579,8 +606,8 @@ export class SessionEngine {
579
606
  });
580
607
  }
581
608
  buildTurnRequest(record, agent, turnId, prompt, isFirstTurn, emit, onUpdate, signal) {
582
- var _a;
583
- var _b;
609
+ var _a, _b, _c;
610
+ var _d;
584
611
  // Per-session cloud attach (channel/tool handoff) forces cloud runtime
585
612
  // even when the agent defaults to local for chat server tools.
586
613
  const runtime = resolveSessionRuntime({
@@ -594,14 +621,24 @@ export class SessionEngine {
594
621
  })
595
622
  : undefined;
596
623
  let turnPrompt = prompt;
624
+ if (isFirstTurn) {
625
+ const contextBlock = buildSessionContextBlock({
626
+ sessionId: record.sessionId,
627
+ channelId: record.channelId,
628
+ channelKind: (_b = (_a = this.channelsById.get(record.channelId)) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.kind,
629
+ environment: isDevMode() ? "local dev server" : "hosted deployment",
630
+ });
631
+ turnPrompt = `${contextBlock}\n\n${prompt}`;
632
+ }
597
633
  if (runtime === "cloud" && isFirstTurn) {
598
634
  const preamble = [
599
- (_b = (_a = agent.instructions) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "",
635
+ (_d = (_c = agent.instructions) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : "",
636
+ buildIdentitySection(agent),
600
637
  buildAgentToolsCatalog(agent.tools, { includeScripts: true }),
601
638
  ]
602
639
  .filter((part) => part !== "")
603
640
  .join("\n\n");
604
- turnPrompt = preamble === "" ? prompt : `${preamble}\n\n${prompt}`;
641
+ turnPrompt = `${preamble}\n\n${turnPrompt}`;
605
642
  }
606
643
  return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ sessionId: record.sessionId }, (record.sdkAgentId === undefined
607
644
  ? {}
@@ -996,11 +1033,22 @@ export class SessionEngine {
996
1033
  }
997
1034
  queueDispatch(sessionId, event) {
998
1035
  var _a;
999
- const chain = (_a = this.dispatchChains.get(sessionId)) !== null && _a !== void 0 ? _a : Promise.resolve();
1036
+ var _b;
1037
+ // Single funnel for both append paths (appendEvent + the held-log emit),
1038
+ // so the storage sink sees every durable event exactly once.
1039
+ (_a = this.storage) === null || _a === void 0 ? void 0 : _a.event(event);
1040
+ const chain = (_b = this.dispatchChains.get(sessionId)) !== null && _b !== void 0 ? _b : Promise.resolve();
1000
1041
  const next = chain
1001
1042
  .then(() => this.dispatchEvent(sessionId, event))
1002
1043
  .catch((error) => {
1003
1044
  this.logger(`[agent-serve] event dispatch failed for ${sessionId}: ${describeError(error)}`);
1045
+ })
1046
+ .then(() => {
1047
+ var _a;
1048
+ // Turn-end flush happens here — after the boundary event's handlers
1049
+ // and their record updates settled — so the persisted record carries
1050
+ // the turn's final channel state and continuation token.
1051
+ (_a = this.storage) === null || _a === void 0 ? void 0 : _a.eventDispatched(event);
1004
1052
  });
1005
1053
  this.dispatchChains.set(sessionId, next);
1006
1054
  }
@@ -1127,10 +1175,29 @@ export class SessionEngine {
1127
1175
  */
1128
1176
  abSnapshot(caller, options) {
1129
1177
  return __awaiter(this, void 0, void 0, function* () {
1178
+ var _a;
1179
+ var _b;
1130
1180
  const sessions = yield this.listSessions(caller, options);
1131
1181
  const abConfig = this.project.abConfig;
1132
1182
  const maxPlaygroundSessions = resolveABMaxPlaygroundSessions(abConfig === null || abConfig === void 0 ? void 0 : abConfig.maxPlaygroundSessions);
1133
1183
  const foldedSessions = sessions.slice(0, maxPlaygroundSessions);
1184
+ // Backfill for a replacement host with nothing local to fold (e.g.
1185
+ // lazy-only restore before any session resumed): serve the persisted
1186
+ // aggregate instead of an empty surface. Gated on the host having no
1187
+ // sessions AT ALL — the persisted snapshot spans every principal, so a
1188
+ // caller who merely owns no sessions must not see it. Loaded once per
1189
+ // process (playground polls this route ~every 4s); skip the persist
1190
+ // side effect below — re-saving a restored snapshot would echo stale
1191
+ // data back into the store.
1192
+ if (foldedSessions.length === 0 &&
1193
+ this.storage !== undefined &&
1194
+ (yield this.sessions.list()).length === 0) {
1195
+ (_b = this.restoredAbSnapshot) !== null && _b !== void 0 ? _b : (this.restoredAbSnapshot = this.storage.getLatestAbSnapshot());
1196
+ const restoredSnapshot = yield this.restoredAbSnapshot;
1197
+ if (restoredSnapshot !== undefined) {
1198
+ return restoredSnapshot;
1199
+ }
1200
+ }
1134
1201
  const snapshot = yield buildABSnapshot({
1135
1202
  experiments: this.project.abs,
1136
1203
  agentName: this.project.name,
@@ -1158,6 +1225,10 @@ export class SessionEngine {
1158
1225
  this.logger(`[agent-serve] ab persistSnapshots.save threw: ${describeError(error)}`);
1159
1226
  }
1160
1227
  }
1228
+ else {
1229
+ // defineStorage fallback (throttled inside the coordinator).
1230
+ (_a = this.storage) === null || _a === void 0 ? void 0 : _a.abSnapshot(snapshot);
1231
+ }
1161
1232
  return snapshot;
1162
1233
  });
1163
1234
  }
@@ -1275,12 +1346,14 @@ export class SessionEngine {
1275
1346
  var _a;
1276
1347
  const chain = (_a = this.updateChains.get(sessionId)) !== null && _a !== void 0 ? _a : Promise.resolve();
1277
1348
  const next = chain.then(() => __awaiter(this, void 0, void 0, function* () {
1349
+ var _a;
1278
1350
  const current = yield this.sessions.get(sessionId);
1279
1351
  if (current === undefined) {
1280
1352
  throw new Error(`Session ${sessionId} not found`);
1281
1353
  }
1282
1354
  const updated = Object.assign(Object.assign({}, updater(current)), { updatedAt: new Date().toISOString() });
1283
1355
  yield this.sessions.save(updated);
1356
+ (_a = this.storage) === null || _a === void 0 ? void 0 : _a.sessionRecord(updated);
1284
1357
  return updated;
1285
1358
  }));
1286
1359
  this.updateChains.set(sessionId, next.catch(() => { }));
@@ -1289,6 +1362,167 @@ export class SessionEngine {
1289
1362
  // ==========================================================================
1290
1363
  // Lifecycle
1291
1364
  // ==========================================================================
1365
+ /**
1366
+ * Restore sessions from the authored storage sink. Called once at
1367
+ * serve start, before channels accept traffic: any persisted session
1368
+ * missing from the local `--state-root` is materialized there — events
1369
+ * as `events.ndjson`, record as `session.json` — after which every
1370
+ * existing read path (continuation lookup, event replay/streams, A/B
1371
+ * fold hydration) works unchanged. Local state always wins over the
1372
+ * sink, so restarts on the same host are no-ops.
1373
+ *
1374
+ * Failures are logged and skipped; a broken store (including rows that
1375
+ * violate the SessionRecord shape) never blocks serve start.
1376
+ */
1377
+ restoreStoredSessions() {
1378
+ return __awaiter(this, void 0, void 0, function* () {
1379
+ const storage = this.storage;
1380
+ if (storage === undefined || !storage.canBulkRestore) {
1381
+ return;
1382
+ }
1383
+ const policy = storage.policy.restore;
1384
+ if (policy === "off") {
1385
+ return;
1386
+ }
1387
+ try {
1388
+ yield this.runBulkRestore(storage, policy);
1389
+ }
1390
+ catch (error) {
1391
+ this.logger(`[agent-serve] session restore failed: ${describeError(error)}`);
1392
+ }
1393
+ });
1394
+ }
1395
+ runBulkRestore(storage, policy) {
1396
+ return __awaiter(this, void 0, void 0, function* () {
1397
+ const loaded = yield storage.listSessions();
1398
+ // Guardrails on whatever the sink returned: drop invalid rows and
1399
+ // sessions older than the age window, then restore newest-first under
1400
+ // the count cap. Anything filtered out here stays reachable through
1401
+ // the lazy continuation-lookup path.
1402
+ const cutoff = Date.now() - policy.maxAgeMs;
1403
+ const candidates = loaded
1404
+ .map((record) => ({
1405
+ record,
1406
+ // Numeric timestamp for both the age filter and the sort; a
1407
+ // non-string updatedAt (e.g. a raw DB Date from an untyped sink)
1408
+ // parses to NaN and is dropped instead of crashing serve start.
1409
+ updatedAt: typeof (record === null || record === void 0 ? void 0 : record.updatedAt) === "string"
1410
+ ? Date.parse(record.updatedAt)
1411
+ : Number.NaN,
1412
+ }))
1413
+ .filter(({ record, updatedAt }) => typeof (record === null || record === void 0 ? void 0 : record.sessionId) === "string" &&
1414
+ record.sessionId !== "" &&
1415
+ updatedAt >= cutoff)
1416
+ .sort((a, b) => b.updatedAt - a.updatedAt)
1417
+ .slice(0, policy.maxSessions)
1418
+ .map(({ record }) => record);
1419
+ let restored = 0;
1420
+ let budget = policy.maxTotalBytes;
1421
+ // Sink round trips dominate restore latency, so event streams are
1422
+ // fetched with bounded parallelism; writes stay sequential, newest
1423
+ // first, so the byte budget is enforced deterministically.
1424
+ outer: for (let i = 0; i < candidates.length; i += RESTORE_FETCH_CONCURRENCY) {
1425
+ const chunk = candidates.slice(i, i + RESTORE_FETCH_CONCURRENCY);
1426
+ const fetched = yield Promise.all(chunk.map((record) => __awaiter(this, void 0, void 0, function* () {
1427
+ try {
1428
+ // Local state always wins over the sink.
1429
+ if ((yield this.sessions.get(record.sessionId)) !== undefined) {
1430
+ return undefined;
1431
+ }
1432
+ const events = yield storage.listSessionEvents(record.sessionId);
1433
+ return { record, events };
1434
+ }
1435
+ catch (error) {
1436
+ this.logger(`[agent-serve] failed to restore session ${record.sessionId}: ${describeError(error)}`);
1437
+ return undefined;
1438
+ }
1439
+ })));
1440
+ for (const item of fetched) {
1441
+ if (item === undefined) {
1442
+ continue;
1443
+ }
1444
+ const ndjson = eventsNdjson(item.events);
1445
+ // Budget is checked BEFORE anything is written: one oversized
1446
+ // session cannot blow past maxTotalBytes on disk. Skipped sessions
1447
+ // stay reachable through the lazy path.
1448
+ const bytes = Buffer.byteLength(JSON.stringify(item.record), "utf8") +
1449
+ (ndjson === undefined ? 0 : Buffer.byteLength(ndjson, "utf8"));
1450
+ if (bytes > budget) {
1451
+ this.logger(`[agent-serve] session restore stopped at the ${policy.maxTotalBytes}-byte budget after ${restored} session(s); remaining sessions restore lazily on resume`);
1452
+ break outer;
1453
+ }
1454
+ try {
1455
+ yield this.materializeSession(item.record, ndjson);
1456
+ budget -= bytes;
1457
+ restored += 1;
1458
+ }
1459
+ catch (error) {
1460
+ this.logger(`[agent-serve] failed to restore session ${item.record.sessionId}: ${describeError(error)}`);
1461
+ }
1462
+ }
1463
+ }
1464
+ if (restored > 0) {
1465
+ this.logger(`[agent-serve] restored ${restored} session(s) from storage`);
1466
+ }
1467
+ });
1468
+ }
1469
+ /**
1470
+ * Lazy restore: a continuation lookup missed locally, so ask the sink
1471
+ * for that one session and materialize it before resuming. Disk grows
1472
+ * with sessions that are actually resumed, not with history.
1473
+ *
1474
+ * Concurrent misses for the same key (webhook redeliveries, retries)
1475
+ * share one in-flight restore — a second materialization racing the
1476
+ * first resumed turn could truncate events the turn already appended.
1477
+ * Sink errors propagate and fail the send (see
1478
+ * {@link StorageCoordinator.getSessionByContinuation}).
1479
+ */
1480
+ restoreSessionByContinuation(channelId, continuationKey) {
1481
+ const storage = this.storage;
1482
+ if (storage === undefined) {
1483
+ return Promise.resolve(undefined);
1484
+ }
1485
+ const key = `${channelId}\u0000${continuationKey}`;
1486
+ let pending = this.restoreInFlight.get(key);
1487
+ if (pending === undefined) {
1488
+ pending = this.loadAndMaterializeByContinuation(storage, channelId, continuationKey).finally(() => this.restoreInFlight.delete(key));
1489
+ this.restoreInFlight.set(key, pending);
1490
+ }
1491
+ return pending;
1492
+ }
1493
+ loadAndMaterializeByContinuation(storage, channelId, continuationKey) {
1494
+ return __awaiter(this, void 0, void 0, function* () {
1495
+ const record = yield storage.getSessionByContinuation(channelId, continuationKey);
1496
+ if (record === undefined) {
1497
+ // Definitive miss: the caller starts a fresh session under this token.
1498
+ return undefined;
1499
+ }
1500
+ const local = yield this.sessions.get(record.sessionId);
1501
+ if (local !== undefined) {
1502
+ return local;
1503
+ }
1504
+ const events = yield storage.listSessionEvents(record.sessionId);
1505
+ yield this.materializeSession(record, eventsNdjson(events));
1506
+ this.logger(`[agent-serve] lazily restored session ${record.sessionId} from storage`);
1507
+ return record;
1508
+ });
1509
+ }
1510
+ /**
1511
+ * Write one restored session to the local state root. Events land on
1512
+ * disk before the record: a session becomes visible (and addressable via
1513
+ * its continuation key) only with its full stream in place, and the
1514
+ * lazily opened event log hydrates from this file.
1515
+ */
1516
+ materializeSession(record, eventsNdjson) {
1517
+ return __awaiter(this, void 0, void 0, function* () {
1518
+ if (eventsNdjson !== undefined) {
1519
+ const filePath = this.sessions.eventFilePath(record.sessionId);
1520
+ yield mkdir(dirname(filePath), { recursive: true });
1521
+ yield writeFile(filePath, eventsNdjson, "utf8");
1522
+ }
1523
+ yield this.sessions.save(record);
1524
+ });
1525
+ }
1292
1526
  trackBackground(promise) {
1293
1527
  this.backgroundWork.add(promise);
1294
1528
  void promise
@@ -1300,18 +1534,28 @@ export class SessionEngine {
1300
1534
  /** Drain running turns, dispatches, and pending writes, then dispose. */
1301
1535
  close() {
1302
1536
  return __awaiter(this, void 0, void 0, function* () {
1303
- var _a, _b;
1537
+ var _a, _b, _c;
1304
1538
  this.approvals.cancelAll("deny");
1305
1539
  yield Promise.allSettled([...this.activeTurns.values()]);
1306
1540
  yield Promise.allSettled([...this.backgroundWork]);
1307
1541
  yield Promise.allSettled([...this.dispatchChains.values()]);
1308
1542
  yield Promise.allSettled([...this.updateChains.values()]);
1309
1543
  yield this.logs.flushAll();
1544
+ yield (_a = this.storage) === null || _a === void 0 ? void 0 : _a.close();
1310
1545
  yield this.mcpHost.close();
1311
- yield (_b = (_a = this.runner).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
1546
+ yield (_c = (_b = this.runner).dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
1312
1547
  });
1313
1548
  }
1314
1549
  }
1550
+ /** Parallel event-stream loads during the startup bulk restore. */
1551
+ const RESTORE_FETCH_CONCURRENCY = 8;
1552
+ /** NDJSON payload for a restored event stream; undefined when empty. */
1553
+ function eventsNdjson(events) {
1554
+ if (events.length === 0) {
1555
+ return undefined;
1556
+ }
1557
+ return `${events.map((event) => JSON.stringify(event)).join("\n")}\n`;
1558
+ }
1315
1559
  function subagentPrompt(subagent) {
1316
1560
  var _a;
1317
1561
  if (subagent.instructions !== undefined && subagent.instructions !== "") {
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Session list / event fetch for CLI (`sessions`, `session`, chat reattach).
3
+ *
4
+ * Customer-facing errors never include hosting URLs or infra jargon.
5
+ */
6
+ import type { SessionEvent, SessionSummary } from "../types.js";
7
+ import { type RequestAuth } from "./request-headers.js";
8
+ export declare function listSessions(args: {
9
+ baseUrl: string;
10
+ auth?: RequestAuth;
11
+ fetchImpl?: typeof fetch;
12
+ }): Promise<SessionSummary[]>;
13
+ export declare function fetchSessionEvents(args: {
14
+ baseUrl: string;
15
+ sessionId: string;
16
+ auth?: RequestAuth;
17
+ fetchImpl?: typeof fetch;
18
+ }): Promise<SessionEvent[]>;
19
+ /** Format a sessions table (id, channel, mode, turns, running, updated). */
20
+ export declare function formatSessionsTable(sessions: SessionSummary[]): string;
21
+ //# sourceMappingURL=sessions-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-client.d.ts","sourceRoot":"","sources":["../../src/internal/sessions-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE7E,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA8B5B;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuE1B;AAgCD,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CActE"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Session list / event fetch for CLI (`sessions`, `session`, chat reattach).
3
+ *
4
+ * Customer-facing errors never include hosting URLs or infra jargon.
5
+ */
6
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
+ return new (P || (P = Promise))(function (resolve, reject) {
9
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
13
+ });
14
+ };
15
+ import { sanitizeCustomerError } from "./logs-client.js";
16
+ import { mergeRequestHeaders } from "./request-headers.js";
17
+ export function listSessions(args) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ var _a;
20
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
21
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
22
+ let resp;
23
+ try {
24
+ resp = yield fetchImpl(`${baseUrl}/v1/sessions`, {
25
+ headers: mergeRequestHeaders(args.auth),
26
+ });
27
+ }
28
+ catch (error) {
29
+ throw new Error(sanitizeCustomerError(error instanceof Error ? error.message : "Could not list sessions."));
30
+ }
31
+ if (!resp.ok) {
32
+ throw new Error(`Could not list sessions (HTTP ${resp.status}).`);
33
+ }
34
+ const body = (yield resp.json());
35
+ if (!Array.isArray(body.sessions)) {
36
+ return [];
37
+ }
38
+ const out = [];
39
+ for (const row of body.sessions) {
40
+ const parsed = parseSessionSummary(row);
41
+ if (parsed !== undefined) {
42
+ out.push(parsed);
43
+ }
44
+ }
45
+ return out;
46
+ });
47
+ }
48
+ export function fetchSessionEvents(args) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ var _a;
51
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
52
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
53
+ const path = `/v1/session/${encodeURIComponent(args.sessionId)}/events`;
54
+ try {
55
+ const jsonResp = yield fetchImpl(`${baseUrl}${path}?format=json`, {
56
+ headers: mergeRequestHeaders(args.auth),
57
+ });
58
+ if (jsonResp.ok) {
59
+ const body = (yield jsonResp.json());
60
+ if (Array.isArray(body.events)) {
61
+ return body.events;
62
+ }
63
+ }
64
+ else if (jsonResp.status === 404) {
65
+ throw new Error(`Session ${args.sessionId} not found.`);
66
+ }
67
+ else if (jsonResp.status === 403) {
68
+ throw new Error(`Session ${args.sessionId} is not readable by this caller.`);
69
+ }
70
+ }
71
+ catch (error) {
72
+ if (error instanceof Error && error.message.startsWith("Session ")) {
73
+ throw error;
74
+ }
75
+ // Fall through to NDJSON.
76
+ }
77
+ try {
78
+ const resp = yield fetchImpl(`${baseUrl}${path}`, {
79
+ headers: mergeRequestHeaders(args.auth),
80
+ });
81
+ if (resp.status === 404) {
82
+ throw new Error(`Session ${args.sessionId} not found.`);
83
+ }
84
+ if (resp.status === 403) {
85
+ throw new Error(`Session ${args.sessionId} is not readable by this caller.`);
86
+ }
87
+ if (!resp.ok) {
88
+ throw new Error(`Could not fetch session events (HTTP ${resp.status}).`);
89
+ }
90
+ const text = yield resp.text();
91
+ const events = [];
92
+ for (const line of text.split("\n")) {
93
+ if (line.trim() === "") {
94
+ continue;
95
+ }
96
+ try {
97
+ events.push(JSON.parse(line));
98
+ }
99
+ catch (_b) {
100
+ // skip malformed lines
101
+ }
102
+ }
103
+ return events;
104
+ }
105
+ catch (error) {
106
+ if (error instanceof Error && error.message.startsWith("Session ")) {
107
+ throw error;
108
+ }
109
+ if (error instanceof Error && error.message.startsWith("Could not fetch")) {
110
+ throw new Error(sanitizeCustomerError(error.message));
111
+ }
112
+ throw new Error(sanitizeCustomerError(error instanceof Error
113
+ ? error.message
114
+ : "Could not fetch session events."));
115
+ }
116
+ });
117
+ }
118
+ /** Lenient parse so partial stubs / older servers still list by sessionId. */
119
+ function parseSessionSummary(value) {
120
+ if (typeof value !== "object" || value === null) {
121
+ return undefined;
122
+ }
123
+ const row = value;
124
+ if (typeof row.sessionId !== "string" || row.sessionId === "") {
125
+ return undefined;
126
+ }
127
+ const continuationToken = typeof row.continuationToken === "string"
128
+ ? row.continuationToken
129
+ : row.continuationToken === null
130
+ ? null
131
+ : null;
132
+ return {
133
+ sessionId: row.sessionId,
134
+ channelId: typeof row.channelId === "string" ? row.channelId : "",
135
+ mode: row.mode === "task" ? "task" : "chat",
136
+ title: typeof row.title === "string" ? row.title : undefined,
137
+ turnCount: typeof row.turnCount === "number" ? row.turnCount : 0,
138
+ running: row.running === true,
139
+ createdAt: typeof row.createdAt === "string" ? row.createdAt : "",
140
+ updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : "",
141
+ continuationToken,
142
+ externalUrl: typeof row.externalUrl === "string" ? row.externalUrl : undefined,
143
+ };
144
+ }
145
+ /** Format a sessions table (id, channel, mode, turns, running, updated). */
146
+ export function formatSessionsTable(sessions) {
147
+ if (sessions.length === 0) {
148
+ return "No sessions.\n";
149
+ }
150
+ const header = ["SESSION", "CHANNEL", "MODE", "TURNS", "RUNNING", "UPDATED"];
151
+ const rows = sessions.map((s) => [
152
+ s.sessionId,
153
+ s.channelId,
154
+ s.mode,
155
+ String(s.turnCount),
156
+ s.running ? "yes" : "no",
157
+ s.updatedAt,
158
+ ]);
159
+ return `${renderTable(header, rows)}\n`;
160
+ }
161
+ function renderTable(header, rows) {
162
+ const widths = header.map((h, i) => Math.max(h.length, ...rows.map((row) => { var _a; return ((_a = row[i]) !== null && _a !== void 0 ? _a : "").length; })));
163
+ const renderRow = (row) => row
164
+ .map((cell, i) => { var _a; return cell.padEnd((_a = widths[i]) !== null && _a !== void 0 ? _a : 0); })
165
+ .join(" ")
166
+ .trimEnd();
167
+ return [renderRow(header), ...rows.map(renderRow)].join("\n");
168
+ }