@cursor/july 0.1.35 → 0.1.37

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 (198) hide show
  1. package/AGENTS.md +5 -9
  2. package/README.md +5 -9
  3. package/dist/channels/github/github-channel.d.ts +1 -1
  4. package/dist/channels/github/github-channel.js +1 -1
  5. package/dist/channels/github/index.d.ts +1 -1
  6. package/dist/channels/github/index.js +1 -1
  7. package/dist/channels/slack/api.js +1 -1
  8. package/dist/channels/slack/index.d.ts +1 -1
  9. package/dist/channels/slack/index.js +1 -1
  10. package/dist/channels/slack/init.d.ts.map +1 -1
  11. package/dist/channels/slack/init.js +2 -1
  12. package/dist/docs/404.html +2 -2
  13. package/dist/docs/ab.html +8 -17
  14. package/dist/docs/assets/{ab.md.DAQoJ-up.js → ab.md.6cLOW7--.js} +4 -13
  15. package/dist/docs/assets/{ab.md.DAQoJ-up.lean.js → ab.md.6cLOW7--.lean.js} +1 -1
  16. package/dist/docs/assets/{app.D5Mv1T0U.js → app.Bu9SRvZ9.js} +1 -1
  17. package/dist/docs/assets/{building-with-agents.md.CnHqvYDd.js → building-with-agents.md.txrcGU2B.js} +2 -2
  18. package/dist/docs/assets/chunks/@localSearchIndexroot.pVFW7oJd.js +1 -0
  19. package/dist/docs/assets/chunks/{VPLocalSearchBox.CMq_BQce.js → VPLocalSearchBox.D9u9czHO.js} +1 -1
  20. package/dist/docs/assets/chunks/{theme.C6D9UPLK.js → theme.Bc61GzOf.js} +2 -2
  21. package/dist/docs/assets/{concepts.md.DFaQEFkA.js → concepts.md.CqOsxbMU.js} +1 -1
  22. package/dist/docs/assets/{deployment.md.9MYBuKM1.js → deployment.md.CuK5SNjN.js} +1 -1
  23. package/dist/docs/assets/{evals.md.BIUoVZ6X.js → evals.md.BQXI3rXy.js} +9 -15
  24. package/dist/docs/assets/{evals.md.BIUoVZ6X.lean.js → evals.md.BQXI3rXy.lean.js} +1 -1
  25. package/dist/docs/assets/{example-agents_approval-buddy.md.BhEfleVx.js → example-agents_approval-buddy.md.CIiZ9coo.js} +1 -1
  26. package/dist/docs/assets/{example-agents_benny.md.2Et1qa8f.js → example-agents_benny.md.l7JTmm8X.js} +1 -1
  27. package/dist/docs/assets/{example-agents_bugbot.md.ByUexi5i.js → example-agents_bugbot.md.Dp5JqHSQ.js} +2 -2
  28. package/dist/docs/assets/{example-agents_bugbot.md.ByUexi5i.lean.js → example-agents_bugbot.md.Dp5JqHSQ.lean.js} +1 -1
  29. package/dist/docs/assets/{example-agents_codebase-wiki.md.B4y-7ZVW.js → example-agents_codebase-wiki.md.D-lteFf0.js} +1 -1
  30. package/dist/docs/assets/{example-agents_codebase-wiki.md.B4y-7ZVW.lean.js → example-agents_codebase-wiki.md.D-lteFf0.lean.js} +1 -1
  31. package/dist/docs/assets/{example-agents_codeowners-review.md.D6ay4nvf.js → example-agents_codeowners-review.md.BU2ZXLf-.js} +1 -1
  32. package/dist/docs/assets/{example-agents_codeowners-review.md.D6ay4nvf.lean.js → example-agents_codeowners-review.md.BU2ZXLf-.lean.js} +1 -1
  33. package/dist/docs/assets/{example-agents_concierge.md.lL8rhYlj.js → example-agents_concierge.md.DA2al_NK.js} +2 -2
  34. package/dist/docs/assets/{example-agents_concierge.md.lL8rhYlj.lean.js → example-agents_concierge.md.DA2al_NK.lean.js} +1 -1
  35. package/dist/docs/assets/{example-agents_fsd.md.DfNKQTHz.js → example-agents_fsd.md.DPz9ezO4.js} +1 -1
  36. package/dist/docs/assets/{example-agents_knowledge-base.md.CzyZ2DCr.js → example-agents_knowledge-base.md.IneynQSR.js} +1 -1
  37. package/dist/docs/assets/{example-agents_oncall.md.wFFXXEyW.js → example-agents_oncall.md.ZE0n6ZFN.js} +1 -1
  38. package/dist/docs/assets/{example-agents_slack-agent.md.DvgvT4nn.js → example-agents_slack-agent.md.06jQXTAI.js} +1 -1
  39. package/dist/docs/assets/{example-agents_weather-agent.md.BADkPqxQ.js → example-agents_weather-agent.md.CrGZ0SqR.js} +3 -3
  40. package/dist/docs/assets/{example-agents_weather-agent.md.BADkPqxQ.lean.js → example-agents_weather-agent.md.CrGZ0SqR.lean.js} +1 -1
  41. package/dist/docs/assets/guides_cloud-runtime.md.V5igN4Sq.js +9 -0
  42. package/dist/docs/assets/guides_cloud-runtime.md.V5igN4Sq.lean.js +1 -0
  43. package/dist/docs/assets/{guides_webhooks.md.DiAwSR42.js → guides_webhooks.md.BERuBSJW.js} +1 -1
  44. package/dist/docs/assets/{hillclimbing.md.D9Y1_bYh.js → hillclimbing.md.yXqdlv2R.js} +1 -1
  45. package/dist/docs/assets/index.md.CmhptOmN.js +24 -0
  46. package/dist/docs/assets/{index.md.CZqbBJPB.lean.js → index.md.CmhptOmN.lean.js} +1 -1
  47. package/dist/docs/assets/{quickstart.md.TnEXYgYW.js → quickstart.md.C_b6ESpD.js} +7 -4
  48. package/dist/docs/assets/{quickstart.md.TnEXYgYW.lean.js → quickstart.md.C_b6ESpD.lean.js} +1 -1
  49. package/dist/docs/assets/{reference_agent-config.md.kuN6-OxK.js → reference_agent-config.md.CRmkoxd6.js} +6 -4
  50. package/dist/docs/assets/{reference_agent-config.md.kuN6-OxK.lean.js → reference_agent-config.md.CRmkoxd6.lean.js} +1 -1
  51. package/dist/docs/assets/reference_artifacts.md.BGG4bZo-.js +19 -0
  52. package/dist/docs/assets/reference_artifacts.md.BGG4bZo-.lean.js +1 -0
  53. package/dist/docs/assets/{reference_channels.md.CDhTRfUz.js → reference_channels.md.BIabFUAI.js} +2 -2
  54. package/dist/docs/assets/{reference_channels.md.CDhTRfUz.lean.js → reference_channels.md.BIabFUAI.lean.js} +1 -1
  55. package/dist/docs/assets/{reference_cli.md.sD-IUWjg.js → reference_cli.md.Byvrg8eu.js} +15 -9
  56. package/dist/docs/assets/{reference_cli.md.sD-IUWjg.lean.js → reference_cli.md.Byvrg8eu.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_hooks.md.DyLVfE1O.js → reference_hooks.md.BGDw4VLm.js} +2 -2
  58. package/dist/docs/assets/{reference_hooks.md.DyLVfE1O.lean.js → reference_hooks.md.BGDw4VLm.lean.js} +1 -1
  59. package/dist/docs/assets/reference_http-api.md.DGrw_wOu.js +11 -0
  60. package/dist/docs/assets/reference_http-api.md.DGrw_wOu.lean.js +1 -0
  61. package/dist/docs/assets/{reference_project-layout.md.D8E6ZmHJ.js → reference_project-layout.md._XdeMahr.js} +2 -2
  62. package/dist/docs/assets/{reference_project-layout.md.D8E6ZmHJ.lean.js → reference_project-layout.md._XdeMahr.lean.js} +1 -1
  63. package/dist/docs/assets/{reference_sessions.md.C_ouF_uf.js → reference_sessions.md.DBVFi2Sx.js} +2 -2
  64. package/dist/docs/assets/{reference_subagents.md.zWAMNfi1.js → reference_subagents.md.DSrGLIuB.js} +2 -2
  65. package/dist/docs/assets/{reference_subagents.md.zWAMNfi1.lean.js → reference_subagents.md.DSrGLIuB.lean.js} +1 -1
  66. package/dist/docs/assets/{reference_tools.md.BswAQM41.js → reference_tools.md.lSrsTxYJ.js} +4 -4
  67. package/dist/docs/assets/{reference_tools.md.BswAQM41.lean.js → reference_tools.md.lSrsTxYJ.lean.js} +1 -1
  68. package/dist/docs/assets/scaffolding-agents.md.mkc3B_ZW.js +1 -0
  69. package/dist/docs/assets/{scaffolding-agents.md.Bsr9Pwzu.lean.js → scaffolding-agents.md.mkc3B_ZW.lean.js} +1 -1
  70. package/dist/docs/assets/{storage.md.xZoiGM58.js → storage.md.mQDtIULc.js} +3 -3
  71. package/dist/docs/assets/{storage.md.xZoiGM58.lean.js → storage.md.mQDtIULc.lean.js} +1 -1
  72. package/dist/docs/building-with-agents.html +6 -6
  73. package/dist/docs/concepts.html +5 -5
  74. package/dist/docs/deployment.html +6 -6
  75. package/dist/docs/evals.html +13 -19
  76. package/dist/docs/example-agents/approval-buddy.html +5 -5
  77. package/dist/docs/example-agents/benny.html +5 -5
  78. package/dist/docs/example-agents/bugbot.html +5 -5
  79. package/dist/docs/example-agents/codebase-wiki.html +5 -5
  80. package/dist/docs/example-agents/codeowners-review.html +5 -5
  81. package/dist/docs/example-agents/concierge.html +6 -6
  82. package/dist/docs/example-agents/fsd.html +5 -5
  83. package/dist/docs/example-agents/index.html +4 -4
  84. package/dist/docs/example-agents/knowledge-base.html +5 -5
  85. package/dist/docs/example-agents/oncall.html +5 -5
  86. package/dist/docs/example-agents/security-reviewer.html +4 -4
  87. package/dist/docs/example-agents/slack-agent.html +5 -5
  88. package/dist/docs/example-agents/weather-agent.html +6 -6
  89. package/dist/docs/guides/agent-to-agent.html +5 -5
  90. package/dist/docs/guides/cloud-runtime.html +6 -6
  91. package/dist/docs/guides/github.html +4 -4
  92. package/dist/docs/guides/human-in-the-loop.html +4 -4
  93. package/dist/docs/guides/mcp-oauth.html +5 -5
  94. package/dist/docs/guides/slack.html +4 -4
  95. package/dist/docs/guides/webhooks.html +6 -6
  96. package/dist/docs/hashmap.json +1 -1
  97. package/dist/docs/hillclimbing.html +6 -6
  98. package/dist/docs/index.html +11 -7
  99. package/dist/docs/quickstart.html +10 -7
  100. package/dist/docs/reference/agent-config.html +10 -8
  101. package/dist/docs/reference/artifacts.html +43 -0
  102. package/dist/docs/reference/channels.html +6 -6
  103. package/dist/docs/reference/cli.html +18 -12
  104. package/dist/docs/reference/connections.html +4 -4
  105. package/dist/docs/reference/hooks.html +6 -6
  106. package/dist/docs/reference/http-api.html +7 -7
  107. package/dist/docs/reference/instructions.html +4 -4
  108. package/dist/docs/reference/playground.html +4 -4
  109. package/dist/docs/reference/project-layout.html +6 -6
  110. package/dist/docs/reference/prompt.html +4 -4
  111. package/dist/docs/reference/schedules.html +4 -4
  112. package/dist/docs/reference/sessions.html +7 -7
  113. package/dist/docs/reference/skills.html +4 -4
  114. package/dist/docs/reference/subagents.html +6 -6
  115. package/dist/docs/reference/tools.html +7 -7
  116. package/dist/docs/scaffolding-agents.html +5 -5
  117. package/dist/docs/storage.html +6 -6
  118. package/dist/docs/troubleshooting.html +4 -4
  119. package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -1
  120. package/dist/files-backends/agent-store-presigned-url.js +15 -22
  121. package/dist/internal/cli-github.d.ts.map +1 -1
  122. package/dist/internal/cli-github.js +8 -7
  123. package/dist/internal/cli-slack.js +9 -9
  124. package/dist/internal/event-mapper.d.ts +3 -3
  125. package/dist/internal/event-mapper.d.ts.map +1 -1
  126. package/dist/internal/event-mapper.js +7 -4
  127. package/dist/internal/session-engine.js +3 -3
  128. package/dist/internal/workspace.d.ts +8 -6
  129. package/dist/internal/workspace.d.ts.map +1 -1
  130. package/dist/internal/workspace.js +15 -11
  131. package/dist/playground/assets/{index-D7OV8B_H.js → index-DRtusTV1.js} +38 -38
  132. package/dist/playground/assets/index-DZp6n4bv.css +1 -0
  133. package/dist/playground/index.html +2 -2
  134. package/docs/README.md +32 -13
  135. package/docs/ab.md +23 -36
  136. package/docs/building-with-agents.md +2 -2
  137. package/docs/concepts.md +3 -2
  138. package/docs/deployment.md +1 -1
  139. package/docs/evals.md +102 -33
  140. package/docs/example-agents/approval-buddy.md +2 -1
  141. package/docs/example-agents/benny.md +2 -0
  142. package/docs/example-agents/bugbot.md +3 -0
  143. package/docs/example-agents/codebase-wiki.md +2 -0
  144. package/docs/example-agents/codeowners-review.md +2 -0
  145. package/docs/example-agents/concierge.md +1 -0
  146. package/docs/example-agents/fsd.md +1 -0
  147. package/docs/example-agents/knowledge-base.md +2 -0
  148. package/docs/example-agents/oncall.md +2 -0
  149. package/docs/example-agents/slack-agent.md +1 -0
  150. package/docs/example-agents/weather-agent.md +9 -4
  151. package/docs/guides/cloud-runtime.md +11 -4
  152. package/docs/guides/webhooks.md +1 -1
  153. package/docs/hillclimbing.md +1 -1
  154. package/docs/quickstart.md +39 -7
  155. package/docs/reference/agent-config.md +74 -14
  156. package/docs/reference/artifacts.md +117 -0
  157. package/docs/reference/channels.md +45 -15
  158. package/docs/reference/cli.md +141 -20
  159. package/docs/reference/hooks.md +11 -4
  160. package/docs/reference/http-api.md +50 -4
  161. package/docs/reference/project-layout.md +6 -0
  162. package/docs/reference/sessions.md +5 -4
  163. package/docs/reference/subagents.md +5 -3
  164. package/docs/reference/tools.md +23 -7
  165. package/docs/scaffolding-agents.md +11 -2
  166. package/docs/storage.md +27 -2
  167. package/package.json +1 -1
  168. package/src/channels/github/github-channel.ts +1 -1
  169. package/src/channels/github/index.ts +1 -1
  170. package/src/channels/slack/api.ts +1 -1
  171. package/src/channels/slack/index.ts +1 -1
  172. package/src/channels/slack/init.ts +2 -1
  173. package/src/files-backends/agent-store-presigned-url.ts +2 -1
  174. package/src/internal/cli-github.ts +8 -7
  175. package/src/internal/cli-slack.ts +9 -9
  176. package/src/internal/event-mapper.ts +9 -4
  177. package/src/internal/session-engine.ts +3 -3
  178. package/src/internal/workspace.ts +15 -11
  179. package/dist/docs/assets/chunks/@localSearchIndexroot.Cu7b6o1D.js +0 -1
  180. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.js +0 -9
  181. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.lean.js +0 -1
  182. package/dist/docs/assets/index.md.CZqbBJPB.js +0 -20
  183. package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +0 -11
  184. package/dist/docs/assets/reference_http-api.md.CfVM_ICa.lean.js +0 -1
  185. package/dist/docs/assets/scaffolding-agents.md.Bsr9Pwzu.js +0 -1
  186. package/dist/playground/assets/index-DOb96C0M.css +0 -1
  187. /package/dist/docs/assets/{building-with-agents.md.CnHqvYDd.lean.js → building-with-agents.md.txrcGU2B.lean.js} +0 -0
  188. /package/dist/docs/assets/{concepts.md.DFaQEFkA.lean.js → concepts.md.CqOsxbMU.lean.js} +0 -0
  189. /package/dist/docs/assets/{deployment.md.9MYBuKM1.lean.js → deployment.md.CuK5SNjN.lean.js} +0 -0
  190. /package/dist/docs/assets/{example-agents_approval-buddy.md.BhEfleVx.lean.js → example-agents_approval-buddy.md.CIiZ9coo.lean.js} +0 -0
  191. /package/dist/docs/assets/{example-agents_benny.md.2Et1qa8f.lean.js → example-agents_benny.md.l7JTmm8X.lean.js} +0 -0
  192. /package/dist/docs/assets/{example-agents_fsd.md.DfNKQTHz.lean.js → example-agents_fsd.md.DPz9ezO4.lean.js} +0 -0
  193. /package/dist/docs/assets/{example-agents_knowledge-base.md.CzyZ2DCr.lean.js → example-agents_knowledge-base.md.IneynQSR.lean.js} +0 -0
  194. /package/dist/docs/assets/{example-agents_oncall.md.wFFXXEyW.lean.js → example-agents_oncall.md.ZE0n6ZFN.lean.js} +0 -0
  195. /package/dist/docs/assets/{example-agents_slack-agent.md.DvgvT4nn.lean.js → example-agents_slack-agent.md.06jQXTAI.lean.js} +0 -0
  196. /package/dist/docs/assets/{guides_webhooks.md.DiAwSR42.lean.js → guides_webhooks.md.BERuBSJW.lean.js} +0 -0
  197. /package/dist/docs/assets/{hillclimbing.md.D9Y1_bYh.lean.js → hillclimbing.md.yXqdlv2R.lean.js} +0 -0
  198. /package/dist/docs/assets/{reference_sessions.md.C_ouF_uf.lean.js → reference_sessions.md.DBVFi2Sx.lean.js} +0 -0
@@ -142,7 +142,7 @@ The `events` map subscribes the channel to stream events for the
142
142
  sessions it owns. Typical wiring: `message.completed` posts the
143
143
  assistant text back to the caller's surface, and `turn.failed` posts an
144
144
  error notice. The full vocabulary is in
145
- [Sessions and streaming](../reference/sessions.md#the-event-vocabulary).
145
+ [Sessions and streaming](../reference/sessions.md#which-events-can-i-stream).
146
146
 
147
147
  ## Auth: loopback by default, on purpose
148
148
 
@@ -56,7 +56,7 @@ Pin the input first. A moving fixture is noise. For GitHub agents, use `agent-sd
56
56
 
57
57
  ## How do I run one hillclimb round?
58
58
 
59
- **Measure.** Hit the agent the way a user would: playground, channel HTTP, or Slack in `--dev`. Or ask the hillclimb skill to do it. `agent-sdk run` returns a JSON trajectory and writes a trace under `.agent-sdk/traces/`.
59
+ **Measure.** Hit the agent the way a user would: playground, channel HTTP, or Slack in `--dev`. Or ask the hillclimb skill to do it. `agent-sdk run` returns a JSON trajectory and writes a trace under `.agent-serve/traces/`.
60
60
 
61
61
  **Reflect.** Score the trajectory, not impressions. Was the answer right? Did the model thrash (too many tools, fat evidence, grep loops)? Did it invent work the host should have prepared? Name the single dominant problem for this round in one sentence. Example: "Full-file dumps trigger grep loops."
62
62
 
@@ -19,8 +19,12 @@ inspectable in the playground.
19
19
  You need:
20
20
 
21
21
  - Node 22.13 or newer. Bun isn't supported.
22
- - The `agent-sdk` CLI. See [Run the CLI](./README.md#run-the-cli)
23
- for the current package and command names.
22
+ - The `agent-sdk` CLI. `npx @cursor/july init ./pr-approver` bootstraps
23
+ it with no prior install: `init` scaffolds the project, runs
24
+ `npm install`, and offers a Cursor sign-in, after which `npx agent-sdk`
25
+ resolves from the project's own dependencies. See
26
+ [Run the CLI](./README.md#run-the-cli) for other setups, such as a
27
+ monorepo source checkout.
24
28
  - A Cursor credential for model turns. Sign in once:
25
29
 
26
30
  ```bash
@@ -34,6 +38,28 @@ You can also set `CURSOR_API_KEY` instead of signing in.
34
38
  automatically. Reading pull requests works on any public repo;
35
39
  posting reviews needs write access to the repo you review.
36
40
 
41
+ ## First run in 10 minutes
42
+
43
+ Want a working agent before the full tutorial? Four commands get you
44
+ there:
45
+
46
+ ```bash
47
+ agent-sdk init ./pr-approver # scaffold + npm install + sign-in offer
48
+ cd pr-approver
49
+ agent-sdk dev # serve, and print the playground URL
50
+ ```
51
+
52
+ Open the playground URL and chat with the scaffold. Then, in a second
53
+ terminal (`dev` keeps running), run one turn from the command line:
54
+
55
+ ```bash
56
+ agent-sdk run --dir . --message "Introduce yourself in one sentence."
57
+ ```
58
+
59
+ That's the whole loop: files become an agent, `dev` serves it, and
60
+ `run` exercises it. The rest of this page turns that scaffold into a
61
+ real PR approver.
62
+
37
63
  ## Scaffolding Agents
38
64
 
39
65
  Have Cursor read [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md)
@@ -74,6 +100,7 @@ pr-approver/
74
100
  │ ├── subagents/
75
101
  │ ├── channels/
76
102
  │ ├── hooks/
103
+ │ │ └── memory.ts
77
104
  │ ├── ab/
78
105
  │ ├── schedules/
79
106
  │ ├── sandbox/workspace/
@@ -84,11 +111,16 @@ pr-approver/
84
111
  ```
85
112
 
86
113
  `agent.ts` holds the model and runtime settings. `instructions.md` is
87
- the always-on system prompt. Each file under `agent/tools/` becomes a
88
- tool. `tsconfig.json` type-checks the project (`npm run check`); the
89
- framework runs your TypeScript directly, so nothing compiles.
114
+ the always-on system prompt, and the scaffold's version includes a
115
+ memory section that tells the agent how to consult its journal. Each
116
+ file under `agent/tools/` becomes a tool, and `agent/hooks/memory.ts`
117
+ journals every turn so future sessions can recall past work (delete it
118
+ to opt out). `tsconfig.json` type-checks the project (`npm run check`);
119
+ the framework runs your TypeScript directly, so nothing compiles.
90
120
 
91
- Check the project before you run it:
121
+ `agent-sdk dev` blocks until you stop it. Keep it running and open a
122
+ second terminal for every other command on this page, starting with
123
+ these checks:
92
124
 
93
125
  ```bash
94
126
  agent-sdk validate --dir .
@@ -109,7 +141,7 @@ agent-sdk run --dir . \
109
141
  `run` starts the agent, sends the message, and waits for the final
110
142
  reply. It prints a JSON trajectory with the response, tool calls, and
111
143
  token usage. It also writes an NDJSON trace under
112
- `.agent-sdk/traces/`.
144
+ `.agent-serve/traces/`.
113
145
 
114
146
  ## Teach it to review
115
147
 
@@ -40,7 +40,10 @@ export default defineAgent({
40
40
  | `instructions` | string | Inline instructions. Prefer `instructions.md`; this exists for subagents and generated configs. |
41
41
  | `runtime` | `"local"` or `"cloud"` | Where turns execute. Default `"local"`. |
42
42
  | `cloud` | object | Cloud agent defaults: repos, env, envVars, forwarded to the Cursor SDK. Used when `runtime` is `"cloud"`, and as the base merged under per-session `cloud` send options. |
43
- | `local` | `{ cwd? }` | Local harness defaults; ignored for cloud turns. |
43
+ | `local` | `{ cwd?, workspaceDir?, sandbox? }` | Local harness defaults; ignored for cloud turns. See [Local options](#local-options). |
44
+ | `hosting` | `{ egressDomains?, secretNames? }` | Managed-hosting declarations read by `agent-sdk deploy`: the pod's egress allowlist and the secret names the agent expects. Ignored by local serving. |
45
+ | `concurrency` | `{ maxRunningTurns? }` | Engine-wide turn admission limit. See [Concurrency](#concurrency). |
46
+ | `builtinTools` | `{ reminders? }` | Framework-provided model-facing tools, opted in per capability. See [Built-in tools](#built-in-tools). |
44
47
 
45
48
  ## Choose a model
46
49
 
@@ -71,17 +74,39 @@ this machine. The session id doubles as the SDK agent id, and server
71
74
  tools, skills, sandbox seeds, and tool approvals all apply.
72
75
 
73
76
  `runtime: "cloud"` runs turns on Cursor cloud agents (`bc-…` ids). Pass
74
- a `cloud` block with the repos the VM carries. In-process server
75
- tools are not available, and instructions and agent-tool catalogs are
76
- prepended to the first prompt, because the local session workspace is
77
- not the cloud VM.
78
-
79
- `validate` warns when `runtime: "cloud"` is combined with server tools,
80
- skills, or sandbox seeds that only apply locally. The full capability
77
+ a `cloud` block with the repos the VM carries. Server tools stay
78
+ reachable over authenticated HTTP MCP back to the serve host when
79
+ `--public-url` or `--cloud-tools-url` is set (omitted with a warning
80
+ otherwise), and instructions and agent-tool catalogs are prepended to
81
+ the first prompt, because the local session workspace is not the cloud
82
+ VM.
83
+
84
+ `validate` warns when `runtime: "cloud"` is combined with agent tools,
85
+ skills, or sandbox seeds, which only materialize into local session
86
+ workspaces, and when the `cloud` block is missing. The full capability
81
87
  matrix and the patterns that hold up are in the
82
88
  [Cloud runtime guide](../guides/cloud-runtime.md).
83
89
 
84
- ## Local cwd
90
+ ## Local options
91
+
92
+ `local` sets local-harness defaults, all ignored for cloud turns.
93
+
94
+ `local.workspaceDir` points every session at one shared harness cwd,
95
+ for agents that work inside an existing checkout. It takes precedence
96
+ over `cwd`, and a per-send `workspaceDir` still wins over both. The SDK
97
+ keys its local executor (rules, skills, MCP, ignore mappings) on the
98
+ harness cwd, so a shared directory resolves the workspace once per
99
+ serve process instead of once per session. The trade: sessions share a
100
+ working tree, so a file one turn writes is visible to the next.
101
+
102
+ `local.sandbox` runs the harness inside Cursor's local sandbox. It's
103
+ off by default, matching the SDK: shell then auto-approves and inherits
104
+ the serve process environment, including any credentials the host
105
+ holds. Turn it on for agents whose turns read untrusted input (webhook
106
+ payloads, PR diffs, inbound chat); it's a real tool boundary rather
107
+ than a prompt-level one.
108
+
109
+ ### Local cwd
85
110
 
86
111
  `local.cwd` sets the default parent directory for local harness
87
112
  workspaces. Each session uses `<cwd>/<sessionId>` (absolute, or relative
@@ -104,6 +129,37 @@ channel opens a cloud-attached session per send. That hybrid pattern is
104
129
  covered in
105
130
  [Cloud runtime](../guides/cloud-runtime.md#hybrid-local-agent-cloud-sessions).
106
131
 
132
+ ## Concurrency
133
+
134
+ `concurrency.maxRunningTurns` caps how many model turns run at once
135
+ across all of the agent's sessions (positive integer, hard cap 200).
136
+ When every slot is busy, newly admitted turns queue FIFO instead of
137
+ failing: the stream records a durable `turn.queued` event with the
138
+ queue position, `GET /v1/sessions` reports `queued: true`, and each
139
+ queued turn starts as soon as a slot frees. A queued turn still counts
140
+ as running for busy semantics: follow-ups preempt it, and direct tool
141
+ calls get `409 session_busy`. Omit for unlimited.
142
+
143
+ ```ts
144
+ export default defineAgent({
145
+ concurrency: { maxRunningTurns: 3 },
146
+ });
147
+ ```
148
+
149
+ ## Built-in tools
150
+
151
+ `builtinTools` opts into framework-provided model-facing tools. Each
152
+ enabled capability materializes as ordinary server tools at discovery
153
+ time, so turns, direct calls, `info`, and the playground treat them
154
+ like authored tools. Authored tools with the same name win, with a
155
+ warning, and like all server tools they run on the local runtime.
156
+
157
+ `builtinTools: { reminders: true }` adds three tools bound to the
158
+ current conversation over `host.reminders`: `reminders_create`,
159
+ `reminders_list`, and `reminders_cancel`. Sessions without a
160
+ continuation key can't arm reminders. See
161
+ [Schedules and reminders](./schedules.md#reminders).
162
+
107
163
  ## Generate instructions
108
164
 
109
165
  When the system prompt must be computed, author `agent/instructions.ts`
@@ -137,11 +193,15 @@ console.log(`listening on ${handle.url}`);
137
193
  ```
138
194
 
139
195
  `ServeOptions` mirrors the CLI flags: `port`, `host`, `dev`,
140
- `stateRoot`, `apiKey`, `schedules`, `reminders`, `playground`,
141
- `authToken` (the `--bearer-token` equivalent), `allowAnonymous`,
142
- `publicUrl`, `cursorEvents`, and `mode: "single" | "multi"`. The Cursor
143
- credential resolves in one order everywhere: explicit `apiKey`, then
144
- `CURSOR_API_KEY`, then the key stored by `agent-sdk login`.
196
+ `stateRoot`, `apiKey`, `schedules`, `reminders`, `noControlPlane`,
197
+ `playground`, `docs`, `authToken` (the `--bearer-token` equivalent),
198
+ `allowAnonymous`, `allowAnonymousCursorGithub`,
199
+ `allowAnonymousCursorAccountMcp`, `cursorGithubProxy`, `publicUrl`,
200
+ `cloudToolsUrl`, `cursorEvents`, and `logger`. `serve()` additionally
201
+ accepts `discovery` (project-loading options) and
202
+ `mode: "single" | "multi"`. The Cursor credential resolves in one order
203
+ everywhere: explicit `apiKey`, then `CURSOR_API_KEY`, then the key
204
+ stored by `agent-sdk login`.
145
205
 
146
206
  ## What's next
147
207
 
@@ -0,0 +1,117 @@
1
+ ---
2
+ title: "Artifacts"
3
+ description: "Tag durable outputs (reviewed PRs, reports) so they persist across sessions, stream as events, and list over HTTP."
4
+ ---
5
+
6
+ # Artifacts
7
+
8
+ An artifact marks a durable output the agent produced: a reviewed PR
9
+ URL, a generated report, a decision record. Sessions come and go;
10
+ artifacts persist across them, capped and listable, so the people
11
+ supervising an agent see what it shipped without replaying event
12
+ streams.
13
+
14
+ ## Declare kinds
15
+
16
+ Author `agent/artifacts.ts` with `defineArtifacts` from
17
+ `@cursor/july/artifacts`:
18
+
19
+ ```ts
20
+ import { z } from "zod";
21
+ import { defineArtifacts } from "@cursor/july/artifacts";
22
+
23
+ export default defineArtifacts({
24
+ kinds: {
25
+ "reviewed-pr": {
26
+ description: "A pull request this agent reviewed.",
27
+ schema: z.object({ url: z.string(), verdict: z.string() }),
28
+ },
29
+ report: { description: "A generated report." },
30
+ },
31
+ agentTool: true,
32
+ });
33
+ ```
34
+
35
+ `defineArtifacts` accepts three fields. `kinds` declares the artifact
36
+ kinds: with kinds declared, `tag` accepts only these; with none, any
37
+ kind string is accepted freeform. Each kind's `description` says what it
38
+ holds and doubles as the model-facing prompt for `tag_artifact`. An
39
+ optional Zod `schema` validates payloads before they persist (the parsed
40
+ output is stored, so defaults and coercions apply). `agentTool` exposes
41
+ the model-facing `tag_artifact` tool generated from the kinds registry;
42
+ it requires at least one declared kind. `max` is the retention cap,
43
+ default 1000: on insert past the cap, the oldest-updated artifact is
44
+ evicted.
45
+
46
+ ## Tag from host code
47
+
48
+ Every handler surface carries `ctx.artifacts` (or `args.artifacts`),
49
+ an `ArtifactsApi` with `tag` and `list`: tools, hooks, channel route
50
+ handlers and `onStart`, schedule `run` handlers, and reminder `run`
51
+ handlers. Tool and hook facades are session-bound, so `tag` auto-fills
52
+ the `sessionId` (and `turnId` when known). Channel, schedule, and
53
+ reminder facades are unbound; pass `sessionId` in the tag input to
54
+ attribute one.
55
+
56
+ ```ts
57
+ await ctx.artifacts.tag({
58
+ kind: "reviewed-pr",
59
+ key: prUrl,
60
+ title: `Reviewed ${prUrl}`,
61
+ data: { url: prUrl, verdict: "approve" },
62
+ });
63
+ ```
64
+
65
+ `key` is the upsert handle: tagging the same key again replaces the
66
+ record instead of creating a new one, so re-reviewing a PR updates one
67
+ row. A `contents` payload (string or bytes, with an optional
68
+ `contentType`) attaches a file or blob served at
69
+ `GET /v1/artifacts/:id/content`; re-tagging a keyed artifact without
70
+ `contents` keeps the existing payload.
71
+
72
+ ## Let the model tag
73
+
74
+ With `agentTool: true`, the `tag_artifact` server tool materializes from
75
+ the kinds registry. Its description tells the model to tag notable
76
+ outputs and lists each kind with its description, and its input schema
77
+ is a discriminated union over the declared kinds, so a schema'd kind is
78
+ validated exactly like a host-side tag. An authored tool named
79
+ `tag_artifact` shadows the built-in, with a warning.
80
+
81
+ ## Observe and list
82
+
83
+ Tagging emits an `artifact.tagged` event on the attributed session's
84
+ stream, carrying the record: `id`, `kind`, `key`, `title`, `data`, and
85
+ `source` (`"host"` for host code, `"model"` for `tag_artifact`). Hooks,
86
+ channel `events`, and evals see it like any other
87
+ [stream event](./sessions.md#which-events-can-i-stream).
88
+
89
+ Over HTTP:
90
+
91
+ ```bash
92
+ curl 'http://127.0.0.1:3000/<slug>/v1/artifacts?kind=reviewed-pr&limit=20'
93
+ curl 'http://127.0.0.1:3000/<slug>/v1/artifacts/<id>/content'
94
+ ```
95
+
96
+ `GET /v1/artifacts` returns records newest-updated first, filterable by
97
+ `kind` and `sessionId`. Session ownership applies, same as
98
+ `/v1/sessions`. The playground renders tagged artifacts too.
99
+
100
+ ## Gate evals on tagging
101
+
102
+ `t.taggedArtifact(kind?, predicate?)` gates an eval on at least one
103
+ artifact tagged during the test turn, optionally of one kind and
104
+ matching a predicate over the record:
105
+
106
+ ```ts
107
+ t.taggedArtifact("reviewed-pr", (record) => record.source === "model");
108
+ ```
109
+
110
+ ## What's next
111
+
112
+ Continue with these pages:
113
+
114
+ - [Sessions and streaming](./sessions.md): the `artifact.tagged` event
115
+ in the full vocabulary
116
+ - [Tools](./tools.md): the `ctx` that carries `artifacts`
117
+ - [Evals](../evals.md): the assertions `taggedArtifact` sits beside
@@ -115,22 +115,34 @@ Handlers receive the Fetch `Request` and an args object:
115
115
 
116
116
  | Member | What it is |
117
117
  | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
118
- | `send(message, options?)` | Run a model turn on this channel; returns the session handle. Options: `continuationToken` (the conversation key), `workspaceFiles`, `workspaceDir`, `cloud` (attach cloud repos for this session), `auth` (defaults to the request principal), `sdkAgentId` (resume a specific SDK agent). |
119
- | `getSession(sessionId)` | Look up an existing session on this channel |
120
- | `receive(channelDefinition, input)` | Hand off to another channel (schedules use this) |
121
- | `callTool(name, input, options?)` | Deterministic server-tool call ([Tools](./tools.md#call-a-tool-without-a-model-turn)) |
122
- | `body`, `query`, `params` | Validated payloads and `:param` path segments |
123
- | `auth` | The `AuthContext` resolved by this route's auth chain |
124
- | `requestIp` | The TCP peer address |
125
- | `host` | Shared services: `host.mcp`, `host.github`, `host.slack`, `host.reminders` |
126
- | `waitUntil(promise)` | Background work that outlives the response |
127
- | `sessionUrls(request, sessionId)` | Absolute playground + trace URLs for a session on this mount |
118
+ | `send(message, options?)` | Run a model turn on this channel; returns the session handle (options below) |
119
+ | `getSession(sessionId)` | Look up an existing session on this channel |
120
+ | `receive(channelDefinition, input)` | Hand off to another channel (schedules use this) |
121
+ | `callTool(name, input, options?)` | Deterministic server-tool call ([Tools](./tools.md#call-a-tool-without-a-model-turn)) |
122
+ | `body`, `query`, `params` | Validated payloads and `:param` path segments |
123
+ | `auth` | The `AuthContext` resolved by this route's auth chain |
124
+ | `requestIp` | The TCP peer address |
125
+ | `host` | Shared services: `host.mcp`, `host.github`, `host.slack`, `host.kv`, `host.files`, `host.reminders` |
126
+ | `waitUntil(promise)` | Background work that outlives the response |
127
+ | `sessionUrls(request, sessionId)` | Absolute playground + trace URLs for a session on this mount |
128
+ | `artifacts` | Unbound [artifacts](./artifacts.md) facade; pass `sessionId` in `tag` input to attribute one |
129
+
130
+ `send` options: `continuationToken` (the conversation key),
131
+ `admission` (`"preempt"` interrupts a busy session, the default;
132
+ `"coalesce"` enqueues behind the running turn, the
133
+ [Slack policy](./sessions.md#what-happens-when-i-send-a-follow-up)),
134
+ `workspaceFiles`, `workspaceDir`, `cloud` (attach cloud repos for this
135
+ session), `auth` (defaults to the request principal), `sdkAgentId`
136
+ (resume a specific SDK agent), `state` (starting channel state for new
137
+ sessions), `title` (session display title), `purpose` (`"eval"` skips
138
+ sticky A/B enrollment), and `coalesceSourceTs` (dedupe key for coalesce
139
+ queue items already delivered mid-turn).
128
140
 
129
141
  ## Events
130
142
 
131
143
  The `events` map subscribes the channel to stream events for the
132
144
  sessions it owns. Keys are event types from the
133
- [event vocabulary](./sessions.md#the-event-vocabulary), or `"*"`.
145
+ [event vocabulary](./sessions.md#which-events-can-i-stream), or `"*"`.
134
146
  Handlers receive `(event, channel, ctx)`, where `channel.state` is the
135
147
  per-session adapter state and `ctx` exposes session info and host
136
148
  services. This is where a channel delivers replies back to its surface.
@@ -139,10 +151,28 @@ services. This is where a channel delivers replies back to its surface.
139
151
 
140
152
  `state` declares the starting per-session adapter state (JSON), persisted
141
153
  on the session record. Routes and event handlers read and mutate it
142
- through `channel.state`. `onStart(args)` runs when the channel mounts. It
143
- receives `send`, `receive`, `callTool`, `host`, and friends; the Slack
144
- pack opens its Socket Mode connection here. `onStop()` runs when the
145
- server drains.
154
+ through `channel.state`. `onStart(args)` runs when the channel mounts;
155
+ the Slack pack opens its Socket Mode connection here. `onStop()` runs
156
+ when the server drains.
157
+
158
+ `onStart` receives the route helpers (`send`, `getSession`, `receive`,
159
+ `callTool`, `host`, `waitUntil`, `artifacts`, and a `logger` that
160
+ respects the server's log sink) plus a set that exists for long-lived
161
+ transports:
162
+
163
+ - `emitAssistantMessage(sessionId, text)` appends an assistant message
164
+ without a model turn, for host tasks that already produced the final
165
+ text.
166
+ - `hasContinuationSession(token)` and `isContinuationBusy(token)`
167
+ report whether a continuation token has a live session and whether a
168
+ turn is in flight on it.
169
+ - `getContinuationLastBotMessageTs(token)` reads the Slack warm-delta
170
+ watermark from channel state.
171
+ - `interruptContinuation(token)` stops the in-flight turn and clears
172
+ coalesced follow-ups queued behind it.
173
+ - `resolveApproval(sessionId, callId, decision, auth, options?)`
174
+ approves or denies a parked tool call, how Slack Block Kit buttons
175
+ unblock a turn without the HTTP approvals route.
146
176
 
147
177
  ## Auth policies
148
178