@cursor/july 0.1.99 → 0.1.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/AGENTS.md +4 -2
  2. package/dist/channels/github/defaults.d.ts.map +1 -1
  3. package/dist/channels/github/defaults.js +28 -3
  4. package/dist/channels/github/progress.d.ts +7 -0
  5. package/dist/channels/github/progress.d.ts.map +1 -1
  6. package/dist/channels/slack/api.d.ts +16 -7
  7. package/dist/channels/slack/api.d.ts.map +1 -1
  8. package/dist/channels/slack/api.js +29 -13
  9. package/dist/channels/slack/constants.d.ts +6 -0
  10. package/dist/channels/slack/constants.d.ts.map +1 -1
  11. package/dist/channels/slack/constants.js +6 -0
  12. package/dist/channels/slack/defaults.d.ts +9 -4
  13. package/dist/channels/slack/defaults.d.ts.map +1 -1
  14. package/dist/channels/slack/defaults.js +154 -76
  15. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  16. package/dist/channels/slack/dispatch.js +3 -3
  17. package/dist/channels/slack/inbound.d.ts +9 -0
  18. package/dist/channels/slack/inbound.d.ts.map +1 -1
  19. package/dist/channels/slack/inbound.js +14 -0
  20. package/dist/channels/slack/index.d.ts +1 -0
  21. package/dist/channels/slack/index.d.ts.map +1 -1
  22. package/dist/channels/slack/index.js +1 -0
  23. package/dist/channels/slack/live-delivery.d.ts +5 -0
  24. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  25. package/dist/channels/slack/live-delivery.js +107 -19
  26. package/dist/channels/slack/reasoning-card.d.ts +38 -0
  27. package/dist/channels/slack/reasoning-card.d.ts.map +1 -0
  28. package/dist/channels/slack/reasoning-card.js +104 -0
  29. package/dist/channels/slack/redact.d.ts +2 -0
  30. package/dist/channels/slack/redact.d.ts.map +1 -0
  31. package/dist/channels/slack/redact.js +5 -0
  32. package/dist/channels/slack/reply-options.d.ts +40 -0
  33. package/dist/channels/slack/reply-options.d.ts.map +1 -0
  34. package/dist/channels/slack/reply-options.js +150 -0
  35. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  36. package/dist/channels/slack/slack-channel.js +8 -4
  37. package/dist/channels/slack/stream.d.ts +22 -10
  38. package/dist/channels/slack/stream.d.ts.map +1 -1
  39. package/dist/channels/slack/stream.js +9 -16
  40. package/dist/channels/slack/tool-cards.d.ts +22 -0
  41. package/dist/channels/slack/tool-cards.d.ts.map +1 -0
  42. package/dist/channels/slack/tool-cards.js +178 -0
  43. package/dist/channels/slack/types.d.ts +145 -6
  44. package/dist/channels/slack/types.d.ts.map +1 -1
  45. package/dist/docs/404.html +2 -2
  46. package/dist/docs/ab.html +6 -6
  47. package/dist/docs/ab.md +1 -1
  48. package/dist/docs/assets/{ab.md.DJo5r4R-.js → ab.md.mlVgqvSk.js} +1 -1
  49. package/dist/docs/assets/{app.BplEAZ3S.js → app.DZ1e0Ycq.js} +1 -1
  50. package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.js → building-with-agents.md.CUSWxlP_.js} +2 -2
  51. package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +1 -0
  52. package/dist/docs/assets/chunks/{VPLocalSearchBox.CHXyv4wP.js → VPLocalSearchBox.l8omwc6D.js} +1 -1
  53. package/dist/docs/assets/chunks/{theme.BTcsZmjQ.js → theme.JVcD6gel.js} +2 -2
  54. package/dist/docs/assets/{evals.md.lfJoEVc8.js → evals.md.CPzDAwoH.js} +1 -1
  55. package/dist/docs/assets/{guides_github.md.Cnh2mL4a.js → guides_github.md.BtPr9GaP.js} +1 -1
  56. package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.js → guides_mcp-oauth.md.Dp6cDP7f.js} +1 -1
  57. package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.js → guides_opentelemetry.md.BVTXDCRg.js} +2 -2
  58. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.js → guides_slack.md.9oHPye9o.js} +19 -3
  59. package/dist/docs/assets/{guides_slack.md.VDXQV3ja.lean.js → guides_slack.md.9oHPye9o.lean.js} +1 -1
  60. package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +4 -0
  61. package/dist/docs/assets/{index.md.CVeRUOeZ.js → index.md.Bb4k8kUm.js} +1 -1
  62. package/dist/docs/assets/{quickstart.md.Nj_LjW_a.js → quickstart.md.DdQOF7Y8.js} +1 -1
  63. package/dist/docs/assets/{reference_connections.md.DxldvyIB.js → reference_connections.md.BiGoBAk2.js} +1 -1
  64. package/dist/docs/assets/scaffolding-agents.md.em43xlY1.js +1 -0
  65. package/dist/docs/assets/skills_ab.md.CsFNatVx.js +26 -0
  66. package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +1 -0
  67. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.js +8 -0
  68. package/dist/docs/assets/skills_create-agent.md.BVoWPcan.lean.js +1 -0
  69. package/dist/docs/assets/skills_debug.md.CDbPhHfg.js +1 -0
  70. package/dist/docs/assets/skills_debug.md.CDbPhHfg.lean.js +1 -0
  71. package/dist/docs/assets/skills_evals.md.723kpUmA.js +25 -0
  72. package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +1 -0
  73. package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +1 -0
  74. package/dist/docs/assets/skills_framework-map.md.BTi817yv.lean.js +1 -0
  75. package/dist/docs/assets/skills_github.md.D0JahM8c.js +16 -0
  76. package/dist/docs/assets/skills_github.md.D0JahM8c.lean.js +1 -0
  77. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +7 -0
  78. package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +1 -0
  79. package/dist/docs/assets/skills_index.md.DKwIxzGg.js +1 -0
  80. package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +1 -0
  81. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +18 -0
  82. package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +1 -0
  83. package/dist/docs/assets/skills_otel.md.CgiZryR3.js +8 -0
  84. package/dist/docs/assets/skills_otel.md.CgiZryR3.lean.js +1 -0
  85. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +20 -0
  86. package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +1 -0
  87. package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.js → troubleshooting.md.Cus_YZga.js} +1 -1
  88. package/dist/docs/building-with-agents.html +6 -6
  89. package/dist/docs/building-with-agents.md +14 -11
  90. package/dist/docs/concepts.html +4 -4
  91. package/dist/docs/deployment.html +4 -4
  92. package/dist/docs/evals.html +6 -6
  93. package/dist/docs/evals.md +1 -1
  94. package/dist/docs/guides/agent-to-agent.html +4 -4
  95. package/dist/docs/guides/cloud-runtime.html +4 -4
  96. package/dist/docs/guides/convert-automation.html +4 -4
  97. package/dist/docs/guides/github.html +5 -5
  98. package/dist/docs/guides/github.md +1 -1
  99. package/dist/docs/guides/human-in-the-loop.html +4 -4
  100. package/dist/docs/guides/mcp-oauth.html +5 -5
  101. package/dist/docs/guides/mcp-oauth.md +1 -1
  102. package/dist/docs/guides/opentelemetry.html +7 -7
  103. package/dist/docs/guides/opentelemetry.md +2 -2
  104. package/dist/docs/guides/slack.html +22 -6
  105. package/dist/docs/guides/slack.md +80 -1
  106. package/dist/docs/guides/webhooks.html +5 -5
  107. package/dist/docs/hashmap.json +1 -1
  108. package/dist/docs/hillclimbing.html +6 -6
  109. package/dist/docs/hillclimbing.md +5 -5
  110. package/dist/docs/index.html +6 -6
  111. package/dist/docs/index.md +1 -1
  112. package/dist/docs/llms-full.txt +1041 -30
  113. package/dist/docs/llms.txt +14 -0
  114. package/dist/docs/quickstart.html +5 -5
  115. package/dist/docs/quickstart.md +1 -1
  116. package/dist/docs/reference/agent-config.html +4 -4
  117. package/dist/docs/reference/artifacts.html +4 -4
  118. package/dist/docs/reference/channels.html +4 -4
  119. package/dist/docs/reference/cli.html +4 -4
  120. package/dist/docs/reference/connections.html +6 -6
  121. package/dist/docs/reference/connections.md +1 -1
  122. package/dist/docs/reference/hooks.html +4 -4
  123. package/dist/docs/reference/http-api.html +4 -4
  124. package/dist/docs/reference/instructions.html +4 -4
  125. package/dist/docs/reference/playground.html +4 -4
  126. package/dist/docs/reference/project-layout.html +4 -4
  127. package/dist/docs/reference/prompt.html +4 -4
  128. package/dist/docs/reference/schedules.html +4 -4
  129. package/dist/docs/reference/sessions.html +4 -4
  130. package/dist/docs/reference/skills.html +4 -4
  131. package/dist/docs/reference/subagents.html +4 -4
  132. package/dist/docs/reference/tools.html +4 -4
  133. package/dist/docs/scaffolding-agents.html +5 -5
  134. package/dist/docs/scaffolding-agents.md +3 -3
  135. package/dist/docs/skills/ab.html +52 -0
  136. package/dist/docs/skills/ab.md +50 -0
  137. package/dist/docs/skills/create-agent.html +34 -0
  138. package/dist/docs/skills/create-agent.md +160 -0
  139. package/dist/docs/skills/debug.html +27 -0
  140. package/dist/docs/skills/debug.md +36 -0
  141. package/dist/docs/skills/evals.html +51 -0
  142. package/dist/docs/skills/evals.md +99 -0
  143. package/dist/docs/skills/framework-map.html +27 -0
  144. package/dist/docs/skills/framework-map.md +95 -0
  145. package/dist/docs/skills/github.html +42 -0
  146. package/dist/docs/skills/github.md +93 -0
  147. package/dist/docs/skills/hillclimb.html +33 -0
  148. package/dist/docs/skills/hillclimb.md +55 -0
  149. package/dist/docs/skills/index.html +27 -0
  150. package/dist/docs/skills/index.md +21 -0
  151. package/dist/docs/skills/mcp-auth.html +44 -0
  152. package/dist/docs/skills/mcp-auth.md +76 -0
  153. package/dist/docs/skills/otel.html +34 -0
  154. package/dist/docs/skills/otel.md +48 -0
  155. package/dist/docs/skills/setup-slack.html +46 -0
  156. package/dist/docs/skills/setup-slack.md +141 -0
  157. package/dist/docs/storage.html +4 -4
  158. package/dist/docs/templates/agentic-owners.html +4 -4
  159. package/dist/docs/templates/agents-md.html +4 -4
  160. package/dist/docs/templates/code-wiki.html +4 -4
  161. package/dist/docs/templates/demo.html +4 -4
  162. package/dist/docs/templates/pr-autofixer.html +4 -4
  163. package/dist/docs/templates/security-help.html +4 -4
  164. package/dist/docs/templates/security-reviewer.html +4 -4
  165. package/dist/docs/templates/triage.html +4 -4
  166. package/dist/docs/troubleshooting.html +5 -5
  167. package/dist/docs/troubleshooting.md +1 -1
  168. package/dist/files-backends/cursor-hosted.d.ts +6 -0
  169. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  170. package/dist/files-backends/cursor-hosted.js +6 -9
  171. package/dist/internal/cli-deploy.js +2 -2
  172. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  173. package/dist/internal/conversation-mirror.js +3 -4
  174. package/dist/internal/cursor/hosted-store-secrets.d.ts +15 -0
  175. package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -0
  176. package/dist/internal/cursor/hosted-store-secrets.js +48 -0
  177. package/dist/internal/deploy-client.d.ts +6 -6
  178. package/dist/internal/deploy-client.js +7 -7
  179. package/dist/internal/discovery.d.ts.map +1 -1
  180. package/dist/internal/discovery.js +11 -1
  181. package/dist/internal/framework-file-storage.d.ts +12 -5
  182. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  183. package/dist/internal/framework-file-storage.js +36 -5
  184. package/dist/internal/framework-storage-selection.d.ts +12 -12
  185. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  186. package/dist/internal/framework-storage-selection.js +33 -39
  187. package/dist/internal/session-run-log.d.ts +3 -3
  188. package/dist/internal/session-run-log.d.ts.map +1 -1
  189. package/dist/internal/session-run-log.js +6 -7
  190. package/dist/internal/storage-coordinator.d.ts +0 -6
  191. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  192. package/dist/internal/storage-coordinator.js +1 -9
  193. package/dist/playground/assets/index-BszoQDc6.css +1 -0
  194. package/dist/playground/assets/{index-jzNbJENa.js → index-DVs98vPL.js} +1 -1
  195. package/dist/playground/index.html +2 -2
  196. package/dist/storage-backends/cursor-hosted-v2.d.ts +83 -0
  197. package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -0
  198. package/dist/storage-backends/cursor-hosted-v2.js +164 -0
  199. package/dist/storage-backends/cursor-hosted.d.ts +6 -0
  200. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  201. package/dist/storage-backends/cursor-hosted.js +6 -1
  202. package/dist/types.d.ts +5 -0
  203. package/dist/types.d.ts.map +1 -1
  204. package/docs/README.md +1 -1
  205. package/docs/ab.md +1 -1
  206. package/docs/building-with-agents.md +14 -11
  207. package/docs/evals.md +1 -1
  208. package/docs/guides/github.md +1 -1
  209. package/docs/guides/mcp-oauth.md +1 -1
  210. package/docs/guides/opentelemetry.md +2 -2
  211. package/docs/guides/slack.md +80 -1
  212. package/docs/hillclimbing.md +5 -5
  213. package/docs/quickstart.md +1 -1
  214. package/docs/reference/connections.md +1 -1
  215. package/docs/scaffolding-agents.md +3 -3
  216. package/docs/skills/index.md +26 -0
  217. package/docs/troubleshooting.md +1 -1
  218. package/package.json +1 -1
  219. package/src/channels/github/defaults.ts +36 -3
  220. package/src/channels/github/progress.ts +7 -0
  221. package/src/channels/slack/api.ts +35 -17
  222. package/src/channels/slack/constants.ts +6 -0
  223. package/src/channels/slack/defaults.ts +173 -92
  224. package/src/channels/slack/dispatch.ts +8 -1
  225. package/src/channels/slack/inbound.ts +17 -0
  226. package/src/channels/slack/index.ts +1 -0
  227. package/src/channels/slack/live-delivery.ts +131 -20
  228. package/src/channels/slack/reasoning-card.ts +140 -0
  229. package/src/channels/slack/redact.ts +6 -0
  230. package/src/channels/slack/reply-options.ts +229 -0
  231. package/src/channels/slack/slack-channel.ts +7 -2
  232. package/src/channels/slack/stream.ts +31 -24
  233. package/src/channels/slack/tool-cards.ts +221 -0
  234. package/src/channels/slack/types.ts +159 -6
  235. package/src/files-backends/cursor-hosted.ts +15 -5
  236. package/src/internal/cli-deploy.ts +2 -2
  237. package/src/internal/conversation-mirror.ts +3 -8
  238. package/src/internal/cursor/hosted-store-secrets.ts +72 -0
  239. package/src/internal/deploy-client.ts +10 -10
  240. package/src/internal/discovery.ts +9 -1
  241. package/src/internal/framework-file-storage.ts +41 -5
  242. package/src/internal/framework-storage-selection.ts +31 -44
  243. package/src/internal/session-run-log.ts +6 -11
  244. package/src/internal/storage-coordinator.ts +1 -11
  245. package/src/storage-backends/cursor-hosted-v2.ts +219 -0
  246. package/src/storage-backends/cursor-hosted.ts +6 -1
  247. package/src/types.ts +5 -0
  248. package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +0 -1
  249. package/dist/docs/assets/hillclimbing.md.DhESf3OO.js +0 -4
  250. package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +0 -1
  251. package/dist/internal/null-kv-storage.d.ts +0 -48
  252. package/dist/internal/null-kv-storage.d.ts.map +0 -1
  253. package/dist/internal/null-kv-storage.js +0 -58
  254. package/dist/playground/assets/index-D7rGZNjy.css +0 -1
  255. package/src/internal/null-kv-storage.ts +0 -74
  256. /package/dist/docs/assets/{ab.md.DJo5r4R-.lean.js → ab.md.mlVgqvSk.lean.js} +0 -0
  257. /package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.lean.js → building-with-agents.md.CUSWxlP_.lean.js} +0 -0
  258. /package/dist/docs/assets/{evals.md.lfJoEVc8.lean.js → evals.md.CPzDAwoH.lean.js} +0 -0
  259. /package/dist/docs/assets/{guides_github.md.Cnh2mL4a.lean.js → guides_github.md.BtPr9GaP.lean.js} +0 -0
  260. /package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.lean.js → guides_mcp-oauth.md.Dp6cDP7f.lean.js} +0 -0
  261. /package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.lean.js → guides_opentelemetry.md.BVTXDCRg.lean.js} +0 -0
  262. /package/dist/docs/assets/{hillclimbing.md.DhESf3OO.lean.js → hillclimbing.md.CpTGTCle.lean.js} +0 -0
  263. /package/dist/docs/assets/{index.md.CVeRUOeZ.lean.js → index.md.Bb4k8kUm.lean.js} +0 -0
  264. /package/dist/docs/assets/{quickstart.md.Nj_LjW_a.lean.js → quickstart.md.DdQOF7Y8.lean.js} +0 -0
  265. /package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.BiGoBAk2.lean.js} +0 -0
  266. /package/dist/docs/assets/{scaffolding-agents.md.D7UUkWw0.lean.js → scaffolding-agents.md.em43xlY1.lean.js} +0 -0
  267. /package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.lean.js → troubleshooting.md.Cus_YZga.lean.js} +0 -0
@@ -11,7 +11,7 @@ event stream for repos you've connected to Cursor. You still declare a
11
11
  `githubChannel` so hooks decide what each event does.
12
12
 
13
13
  The companion skill for coding agents is
14
- [`skills/github/SKILL.md`](../../skills/github/SKILL.md).
14
+ [`skills/github/SKILL.md`](../skills/github.md).
15
15
 
16
16
  ## Pull events from Cursor
17
17
 
@@ -13,7 +13,7 @@ deployment as secrets so prod can reconnect after a redeploy. Hosted
13
13
  Connect lets the current process retry.
14
14
 
15
15
  The companion skill is
16
- [`skills/mcp-auth/SKILL.md`](../../skills/mcp-auth/SKILL.md).
16
+ [`skills/mcp-auth/SKILL.md`](../skills/mcp-auth.md).
17
17
 
18
18
  ## What can host MCP OAuth do?
19
19
 
@@ -91,7 +91,7 @@ You can also pass the same object to `serve(dir, { otel })`. Precedence
91
91
  is `serve({ otel })` over `agent/otel.ts` over env. An empty
92
92
  `defineOtel()` still enables export when `OTEL_EXPORTER_OTLP_*` is set.
93
93
 
94
- The companion skill is [`skills/otel/SKILL.md`](../../skills/otel/SKILL.md).
94
+ The companion skill is [`skills/otel/SKILL.md`](../skills/otel.md).
95
95
 
96
96
  ## What spans does a session produce?
97
97
 
@@ -206,7 +206,7 @@ through `serve({ otel })` or env.
206
206
 
207
207
  ## What's next
208
208
 
209
- - [`skills/otel/SKILL.md`](../../skills/otel/SKILL.md): compact
209
+ - [`skills/otel/SKILL.md`](../skills/otel.md): compact
210
210
  `defineOtel` reference for coding agents
211
211
  - [Hooks](../reference/hooks.md): observe the same session event stream
212
212
  in-process
@@ -12,7 +12,7 @@ Replies stream there, with thinking steps and suggested prompts.
12
12
  Use `agent-sdk slack create` when Cursor should own the Slack app. Use
13
13
  `agent-sdk slack init --manual` when you own it. Commands and flags live
14
14
  in the [CLI reference](../reference/cli.md#slack). Coding agents should
15
- follow [`skills/setup-slack/SKILL.md`](../../skills/setup-slack/SKILL.md).
15
+ follow [`skills/setup-slack/SKILL.md`](../skills/setup-slack.md).
16
16
 
17
17
  ## Define the channel
18
18
 
@@ -55,6 +55,85 @@ export default slackChannel({
55
55
  });
56
56
  ```
57
57
 
58
+ ## Choose how the reply arrives
59
+
60
+ Slack gives an agent two places to show progress while a turn runs: the
61
+ status chip under the thread ("Running grep…") and the reply message
62
+ itself. It won't fill both at once. While a message is streaming, Slack
63
+ shows its own "is working…" chip and hides any status text you set. Cards
64
+ only exist inside a streamed message. `reply.mode` picks which one you get.
65
+
66
+ ### `post` (default): status chip, then one message
67
+
68
+ Tool calls and the first line of each reasoning block show in the chip as
69
+ they happen. The answer lands as a single message when the turn finishes.
70
+
71
+ ```ts
72
+ export default slackChannel({
73
+ reply: {
74
+ mode: "post",
75
+ status: {
76
+ reasoning: true,
77
+ tools: true,
78
+ idle: ["Checking the monorepo…", "Poking Datadog…"],
79
+ },
80
+ },
81
+ });
82
+ ```
83
+
84
+ `idle` is the rotation Slack cycles through when nothing more specific is
85
+ known, up to 5 lines of 50 characters. Pass a function to `tools` to write
86
+ your own line from the calls in flight.
87
+
88
+ ### `stream`: live text, with cards
89
+
90
+ The answer streams into one message as the model writes it. Slack owns the
91
+ chip for the duration, so live feedback inside the message comes from
92
+ cards. Both are off unless you turn them on.
93
+
94
+ ```ts
95
+ export default slackChannel({
96
+ reply: {
97
+ mode: "stream",
98
+ reasoningCard: true,
99
+ toolCards: { group: "per-tool" },
100
+ },
101
+ toolLabels: { grep: "Searching code", read: "Reading files" },
102
+ });
103
+ ```
104
+
105
+ The reasoning card is one task card, titled "Thinking", that receives the
106
+ model's reasoning as it streams and completes when the answer text starts.
107
+ `maxChars` (default 1500) caps how much it collects. Slack caps a streamed
108
+ message near 12k characters including cards; when an answer outgrows that,
109
+ the streamed message closes where it stands and the rest continues in a
110
+ new message.
111
+
112
+ Tool cards default to one card per tool name with a call count in the title
113
+ (`grep ×3`), updated in place as calls finish. `group: "per-call"` shows one
114
+ card per call instead.
115
+
116
+ Cards are collapsible by default: each call adds one line under the title,
117
+ the same summary the playground shows in a tool's header (the grep pattern,
118
+ the file path, the shell command), and the group expands the same way the
119
+ reasoning card does. `collapsible: false` keeps cards to their titles. On a
120
+ collapsible card, `details(call)` returns the line to add when a call starts
121
+ and `output(result)` the text to add when it finishes.
122
+
123
+ `toolLabels` renames tools everywhere they appear: the chip, card titles,
124
+ and the default `Running …` line.
125
+
126
+ ### Migrating from `streaming` and `thinkingSteps`
127
+
128
+ `streaming: false` is `reply: { mode: "post" }`. `streaming: true` is
129
+ `reply: { mode: "stream", toolCards: { group: "per-call", collapsible:
130
+ false } }`, the title-only cards it used to show. `loadingMessages` moves
131
+ to `reply.status.idle`. The old options still work and `agent-sdk validate`
132
+ prints the rewrite for each one.
133
+
134
+ A channel that set none of these used to stream. It now posts. Set
135
+ `reply: { mode: "stream" }` to keep streaming.
136
+
58
137
  ## Set it up
59
138
 
60
139
  `slack create` opens the Cursor dashboard wizard. Finish Slack consent
@@ -22,7 +22,7 @@ flowchart LR
22
22
 
23
23
  ## How do I hillclimb an agent with a coding agent?
24
24
 
25
- Have Cursor read [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md).
25
+ Have Cursor read [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md).
26
26
 
27
27
  Tell it:
28
28
 
@@ -36,10 +36,10 @@ Other skills cover the edges:
36
36
 
37
37
  | When you need… | Skill |
38
38
  | --- | --- |
39
- | The measured improvement loop | [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md) |
40
- | An eval that locks a kept win | [`skills/evals/SKILL.md`](../skills/evals/SKILL.md) |
41
- | Repeatable GitHub webhook inputs | [`skills/github/SKILL.md`](../skills/github/SKILL.md) |
42
- | A run that misbehaves | [`skills/debug/SKILL.md`](../skills/debug/SKILL.md) |
39
+ | The measured improvement loop | [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md) |
40
+ | An eval that locks a kept win | [`skills/evals/SKILL.md`](./skills/evals.md) |
41
+ | Repeatable GitHub webhook inputs | [`skills/github/SKILL.md`](./skills/github.md) |
42
+ | A run that misbehaves | [`skills/debug/SKILL.md`](./skills/debug.md) |
43
43
 
44
44
  See [Building agents with agents](./building-with-agents.md) for every framework skill and a good first prompt.
45
45
 
@@ -13,7 +13,7 @@ review. Add GitHub event handling so pull requests can trigger reviews.
13
13
 
14
14
  - **Get started with an agent in Cursor:** follow
15
15
  [Scaffold an agent with Cursor](./scaffolding-agents.md) and ask Cursor
16
- to read [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md).
16
+ to read [`skills/create-agent/SKILL.md`](./skills/create-agent.md).
17
17
  - **Get started in the CLI:** continue below.
18
18
 
19
19
  ## Prerequisites
@@ -54,7 +54,7 @@ agent-sdk mcp oauth inventory --store # also upsert deployment secrets
54
54
  ```
55
55
 
56
56
  Full walkthrough: [Host MCP OAuth](../guides/mcp-oauth.md). Companion
57
- skill: [`skills/mcp-auth/SKILL.md`](../../skills/mcp-auth/SKILL.md).
57
+ skill: [`skills/mcp-auth/SKILL.md`](../skills/mcp-auth.md).
58
58
 
59
59
  Account MCP (`cursorAccount: true`) is the right choice for connectors
60
60
  already linked in the Cursor dashboard. Omit `servers` (or pass `"*"`)
@@ -11,7 +11,7 @@ decision.
11
11
  ## What does the create-agent skill do?
12
12
 
13
13
  The bundled
14
- [`create-agent` skill](../skills/create-agent/SKILL.md) turns your goal
14
+ [`create-agent` skill](./skills/create-agent.md) turns your goal
15
15
  into a small working project. Have Cursor read that file and follow it.
16
16
 
17
17
  Where to find the file depends on how you got the package:
@@ -26,7 +26,7 @@ Where to find the file depends on how you got the package:
26
26
  - Installed `@cursor/july` as a dependency? The skill also ships inside
27
27
  the package at `node_modules/@cursor/july/skills/create-agent/SKILL.md`.
28
28
  - Working from this package's source? The skill is at
29
- [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md). Run
29
+ [`skills/create-agent/SKILL.md`](./skills/create-agent.md). Run
30
30
  `agent-sdk install-skills` if you want the same copies in
31
31
  `~/.cursor/skills/agentsdk/` (the package postinstall skips the
32
32
  source checkout).
@@ -119,7 +119,7 @@ without a Cursor credential. Model turns and evals need
119
119
 
120
120
  Choose one to three fixed inputs, define what should improve, and name
121
121
  what must stay unchanged. Then have Cursor follow
122
- [`skills/hillclimb/SKILL.md`](../skills/hillclimb/SKILL.md).
122
+ [`skills/hillclimb/SKILL.md`](./skills/hillclimb.md).
123
123
 
124
124
  The hillclimb skill measures a baseline, changes one lever, runs the same
125
125
  inputs again, and adds an eval for each improvement you keep.
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: "Coding-agent skills"
3
+ description: "Task guides that ship with the Agent SDK for scaffolding, evals, channels, and hillclimbing."
4
+ ---
5
+
6
+ # Coding-agent skills
7
+
8
+ Each skill is a procedure a coding agent can follow. Installing
9
+ `@cursor/july` copies them into `~/.cursor/skills/agentsdk/`. This site
10
+ publishes the same files.
11
+
12
+ See [Building agents with agents](../building-with-agents.md) for when
13
+ to use each one.
14
+
15
+ | Skill | Use it to |
16
+ | --- | --- |
17
+ | [framework-map](./framework-map.md) | Learn the project layout and runtimes |
18
+ | [create-agent](./create-agent.md) | Scaffold and verify a new agent |
19
+ | [evals](./evals.md) | Write fixtures and regression checks |
20
+ | [ab](./ab.md) | Compare variants on live traffic |
21
+ | [otel](./otel.md) | Export OpenTelemetry traces |
22
+ | [hillclimb](./hillclimb.md) | Improve an agent against fixed inputs |
23
+ | [github](./github.md) | Add GitHub webhooks and replay events |
24
+ | [setup-slack](./setup-slack.md) | Connect an agent to Slack |
25
+ | [mcp-auth](./mcp-auth.md) | Authorize host MCP OAuth |
26
+ | [debug](./debug.md) | Diagnose a local run |
@@ -74,7 +74,7 @@ not on `PATH`, use `npx @cursor/july`.
74
74
  | Model asks for `mcp_auth` or IDE MCP for a connector it already has | Attached MCP is behind meta-tools. Set `advertiseTools: true` for named tools on local turns, or call it from a host tool via `ctx.host.mcp`. |
75
75
 
76
76
  See [Host MCP OAuth](./guides/mcp-oauth.md) and
77
- [`skills/mcp-auth/SKILL.md`](../skills/mcp-auth/SKILL.md).
77
+ [`skills/mcp-auth/SKILL.md`](./skills/mcp-auth.md).
78
78
 
79
79
  ## What if a secret showed up in a terminal transcript?
80
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor/july",
3
- "version": "0.1.99",
3
+ "version": "0.1.100",
4
4
  "description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {
@@ -27,9 +27,18 @@ export function buildDefaultGitHubEvents(
27
27
  options: BuildDefaultGitHubEventsOptions = {}
28
28
  ): ChannelEventHandlers<GitHubChannelState> {
29
29
  const deliverReplies = options.deliverReplies !== false;
30
+ const requiredSuccessfulTools = new Set(
31
+ options.progress?.requireSuccessfulTools
32
+ ?.map((toolName) => toolName.trim())
33
+ .filter((toolName) => toolName !== "") ?? []
34
+ );
35
+ const toolOutcomesBySession = new Map<string, Map<string, boolean>>();
30
36
 
31
37
  return {
32
- async "turn.started"(_event, channel) {
38
+ async "turn.started"(event, channel) {
39
+ if (requiredSuccessfulTools.size > 0) {
40
+ toolOutcomesBySession.set(event.sessionId, new Map());
41
+ }
33
42
  await applyGitHubProgress({
34
43
  phase: "pending",
35
44
  channel,
@@ -52,9 +61,31 @@ export function buildDefaultGitHubEvents(
52
61
  }
53
62
  },
54
63
 
55
- async "turn.completed"(_event, channel) {
64
+ async "action.result"(event) {
65
+ if (
66
+ event.data.parentCallId !== undefined ||
67
+ !requiredSuccessfulTools.has(event.data.toolName)
68
+ ) {
69
+ return;
70
+ }
71
+ const outcomes = toolOutcomesBySession.get(event.sessionId) ?? new Map();
72
+ outcomes.set(
73
+ event.data.toolName,
74
+ !event.data.isError && event.data.stubbed !== true
75
+ );
76
+ toolOutcomesBySession.set(event.sessionId, outcomes);
77
+ },
78
+
79
+ async "turn.completed"(event, channel) {
80
+ const outcomes = toolOutcomesBySession.get(event.sessionId);
81
+ const pipelineSucceeded =
82
+ requiredSuccessfulTools.size === 0 ||
83
+ [...requiredSuccessfulTools].every(
84
+ (toolName) => outcomes?.get(toolName) === true
85
+ );
86
+ toolOutcomesBySession.delete(event.sessionId);
56
87
  await applyGitHubProgress({
57
- phase: "success",
88
+ phase: pipelineSucceeded ? "success" : "failure",
58
89
  channel,
59
90
  options,
60
91
  });
@@ -82,6 +113,7 @@ export function buildDefaultGitHubEvents(
82
113
  },
83
114
 
84
115
  async "turn.failed"(event, channel) {
116
+ toolOutcomesBySession.delete(event.sessionId);
85
117
  await applyGitHubProgress({
86
118
  phase: "failure",
87
119
  channel,
@@ -91,6 +123,7 @@ export function buildDefaultGitHubEvents(
91
123
  },
92
124
 
93
125
  async "session.failed"(event, channel) {
126
+ toolOutcomesBySession.delete(event.sessionId);
94
127
  await applyGitHubProgress({
95
128
  phase: "failure",
96
129
  channel,
@@ -35,6 +35,13 @@ export type GitHubBannerProgress = GitHubProgressPhaseCopy;
35
35
  export interface GitHubProgressConfig {
36
36
  /** When false, skip the eyes reaction on turn.started. Defaults to true. */
37
37
  reactions?: boolean;
38
+ /**
39
+ * Top-level tools that must each finish successfully before a completed
40
+ * turn is reported as successful. A missing, stubbed, or ultimately failed
41
+ * tool reports failure instead. Later successful retries replace an earlier
42
+ * failure for the same tool.
43
+ */
44
+ requireSuccessfulTools?: readonly string[];
38
45
  /**
39
46
  * Opt-in Checks API run on the PR head. Omit or `false` keeps today's
40
47
  * behavior (no check from default events). With `cursorAccount`, enabling
@@ -16,7 +16,7 @@ import {
16
16
  } from "./constants.js";
17
17
  import { tryResolveAppToken, tryResolveBotToken } from "./credentials.js";
18
18
  import { defaultSlackLog, type SlackLog } from "./log.js";
19
- import type { StreamTaskChunk } from "./stream.js";
19
+ import type { StreamChunk } from "./stream.js";
20
20
  import type {
21
21
  SlackApiTransport,
22
22
  SlackBinding,
@@ -194,10 +194,18 @@ export function truncateTitle(title: string, max?: number): string {
194
194
  // ---------------------------------------------------------------------------
195
195
 
196
196
  /**
197
- * Show or clear the Working chip. Agent UX ignores empty
198
- * `assistant.threads.setStatus`; `agents.sessions.setStatus` `active` is
199
- * what actually clears it. The assistant call stays for loading_messages
200
- * and older workspaces.
197
+ * Show or clear the status chip under the thread.
198
+ *
199
+ * Status text goes through `assistant.threads.setStatus` alone. The agent
200
+ * session is only written when clearing: Agent UX ignores an empty assistant
201
+ * status, so `agents.sessions.setStatus` `active` is what actually drops the
202
+ * chip. That same write must not accompany status text — Slack applies it
203
+ * asynchronously and it blanks the chip when it lands after the text, which
204
+ * reads as flicker between updates. A `processing` write would be worse:
205
+ * Agent UX paints its own generic "is working…" over the assistant text
206
+ * while the session is `processing`. An open `chat.startStream` also flips
207
+ * the session to `processing` on Slack's side, so status text only shows on
208
+ * non-streaming turns. The empty assistant call stays for older workspaces.
201
209
  */
202
210
  export async function setThreadStatus(args: {
203
211
  botToken: SlackBotToken | undefined;
@@ -210,21 +218,12 @@ export async function setThreadStatus(args: {
210
218
  return { ok: false, error: "missing_channel_or_thread" };
211
219
  }
212
220
  const status = truncateTypingStatus(args.status);
213
- const sessionResult = await callSlackApiSoft({
214
- botToken: args.botToken,
215
- operation: "agents.sessions.setStatus",
216
- body: {
217
- channel_id: args.channelId,
218
- thread_ts: args.threadTs,
219
- status: status.length > 0 ? "processing" : "active",
220
- },
221
- });
222
-
223
221
  const body: Record<string, unknown> = {
224
222
  channel_id: args.channelId,
225
223
  thread_ts: args.threadTs,
226
224
  status,
227
225
  };
226
+
228
227
  if (status.length > 0) {
229
228
  const loadingRaw =
230
229
  args.loadingMessages !== undefined && args.loadingMessages.length > 0
@@ -237,7 +236,22 @@ export async function setThreadStatus(args: {
237
236
  if (loading_messages.length > 0) {
238
237
  body.loading_messages = loading_messages;
239
238
  }
239
+ return callSlackApiSoft({
240
+ botToken: args.botToken,
241
+ operation: "assistant.threads.setStatus",
242
+ body,
243
+ });
240
244
  }
245
+
246
+ const sessionResult = await callSlackApiSoft({
247
+ botToken: args.botToken,
248
+ operation: "agents.sessions.setStatus",
249
+ body: {
250
+ channel_id: args.channelId,
251
+ thread_ts: args.threadTs,
252
+ status: "active",
253
+ },
254
+ });
241
255
  const assistantResult = await callSlackApiSoft({
242
256
  botToken: args.botToken,
243
257
  operation: "assistant.threads.setStatus",
@@ -300,7 +314,7 @@ export async function startChatStream(args: {
300
314
  channel: string;
301
315
  thread_ts?: string;
302
316
  markdown_text?: string;
303
- chunks?: StreamTaskChunk[];
317
+ chunks?: StreamChunk[];
304
318
  recipient_user_id?: string;
305
319
  recipient_team_id?: string;
306
320
  }): Promise<SoftSlackResult<{ ts: string; channel: string }>> {
@@ -346,7 +360,7 @@ export async function appendChatStream(args: {
346
360
  channel: string;
347
361
  ts: string;
348
362
  markdown_text?: string;
349
- chunks?: StreamTaskChunk[];
363
+ chunks?: StreamChunk[];
350
364
  }): Promise<SoftSlackResult> {
351
365
  const body: Record<string, unknown> = {
352
366
  channel: args.channel,
@@ -370,6 +384,7 @@ export async function stopChatStream(args: {
370
384
  channel: string;
371
385
  ts: string;
372
386
  markdown_text?: string;
387
+ chunks?: StreamChunk[];
373
388
  blocks?: unknown[];
374
389
  }): Promise<SoftSlackResult> {
375
390
  const body: Record<string, unknown> = {
@@ -379,6 +394,9 @@ export async function stopChatStream(args: {
379
394
  if (args.markdown_text !== undefined) {
380
395
  body.markdown_text = args.markdown_text;
381
396
  }
397
+ if (args.chunks !== undefined && args.chunks.length > 0) {
398
+ body.chunks = args.chunks;
399
+ }
382
400
  if (args.blocks !== undefined && args.blocks.length > 0) {
383
401
  body.blocks = args.blocks;
384
402
  }
@@ -13,6 +13,12 @@ export const SLACK_LOADING_MESSAGE_MAX_LEN = 50;
13
13
  /** Slack `assistant.threads.setStatus` accepts at most 5 `loading_messages`. */
14
14
  export const SLACK_LOADING_MESSAGES_MAX = 5;
15
15
  export const SLACK_TITLE_MAX_LEN = 80;
16
+ /**
17
+ * `markdown_text` (and so a streamed message, cards included) tops out near
18
+ * 12k characters; past it Slack answers `msg_too_long`. Plain `text` allows
19
+ * about 40k.
20
+ */
21
+ export const SLACK_MARKDOWN_TEXT_MAX_LEN = 12_000;
16
22
 
17
23
  /** Rotating assistant status lines (Slack `loading_messages`). */
18
24
  export const SLACK_DEFAULT_LOADING_MESSAGES = [