@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
@@ -1,12 +1,18 @@
1
1
  ---
2
- title: "Build your first weather agent"
3
- description: "Create a weather agent, add a typed tool, run it from the terminal, and open it in the playground."
2
+ title: "Build your first PR approver"
3
+ description: "Create an agent that reviews pull requests by complexity, approves the safe ones, and wakes from GitHub webhooks."
4
4
  ---
5
5
 
6
- # Build your first weather agent
6
+ # Build your first PR approver
7
7
 
8
- Create an agent, give it a weather tool, run a complete turn, and chat
9
- with it in the browser.
8
+ Build an agent that reviews GitHub pull requests. It fetches the diff,
9
+ rates the change's complexity in plain TypeScript, approves the safe
10
+ ones, and flags the rest for a human. Then wire it to GitHub webhooks
11
+ and watch a pull request wake it.
12
+
13
+ The split is the point of the exercise: deterministic policy lives in
14
+ typed tools, judgment lives in the model, and every decision is
15
+ inspectable in the playground.
10
16
 
11
17
  ## Prerequisites
12
18
 
@@ -23,13 +29,18 @@ agentkit login
23
29
 
24
30
  You can also set `CURSOR_API_KEY` instead of signing in.
25
31
 
32
+ - A GitHub credential. `gh auth login` is enough, or set
33
+ `GITHUB_TOKEN`. The tools you write resolve either one
34
+ automatically. Reading pull requests works on any public repo;
35
+ posting reviews needs write access to the repo you review.
36
+
26
37
  ## Scaffolding Agents
27
38
 
28
39
  Have Cursor read [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md)
29
40
  and describe what you want:
30
41
 
31
- > Build me a weather agent for the playground. Start with one weather
32
- > tool and guide me through the remaining decisions.
42
+ > Build me a PR approver for the playground. Start with one tool that
43
+ > inspects a pull request and guide me through the remaining decisions.
33
44
 
34
45
  Cursor asks for missing choices, shows you the plan, then builds and
35
46
  verifies the agent. Continue below to do the same by hand.
@@ -42,25 +53,40 @@ full guided workflow.
42
53
  Start with the built-in scaffold:
43
54
 
44
55
  ```bash
45
- agentkit init ./weather-agent
46
- cd weather-agent
56
+ agentkit init ./pr-approver
57
+ cd pr-approver
58
+ agentkit dev
47
59
  ```
48
60
 
49
- The scaffold creates the files agentkit discovers:
61
+ The scaffold creates the files agentkit discovers, plus empty capability
62
+ folders (each with a `.gitkeep`) so you can drop tools, channels, and
63
+ evals in place:
50
64
 
51
65
  ```text
52
- weather-agent/
66
+ pr-approver/
53
67
  ├── agent/
54
68
  │ ├── agent.ts
55
69
  │ ├── instructions.md
56
- └── tools/
57
- └── echo.ts
58
- └── package.json
70
+ ├── tools/
71
+ └── echo.ts
72
+ │ ├── skills/
73
+ │ ├── mcp-connections/
74
+ │ ├── subagents/
75
+ │ ├── channels/
76
+ │ ├── hooks/
77
+ │ ├── ab/
78
+ │ ├── schedules/
79
+ │ ├── sandbox/workspace/
80
+ │ └── lib/
81
+ ├── evals/
82
+ ├── package.json
83
+ └── tsconfig.json
59
84
  ```
60
85
 
61
86
  `agent.ts` holds the model and runtime settings. `instructions.md` is
62
87
  the always-on system prompt. Each file under `agent/tools/` becomes a
63
- tool.
88
+ tool. `tsconfig.json` type-checks the project (`npm run check`); the
89
+ framework runs your TypeScript directly, so nothing compiles.
64
90
 
65
91
  Check the project before you run it:
66
92
 
@@ -85,18 +111,32 @@ reply. It prints a JSON trajectory with the response, tool calls, and
85
111
  token usage. It also writes an NDJSON trace under
86
112
  `.agentkit/traces/`.
87
113
 
88
- ## Add weather instructions
114
+ ## Teach it to review
89
115
 
90
116
  Replace `agent/instructions.md`:
91
117
 
92
118
  ```md
93
- # Weather agent
94
-
95
- You are a concise weather assistant.
96
-
97
- - Use `get_weather` before answering questions about current weather.
98
- - Tell the user the weather data is simulated.
99
- - Keep replies to two sentences or fewer.
119
+ # PR approver
120
+
121
+ You review GitHub pull requests. Be specific and brief.
122
+
123
+ For every pull request:
124
+
125
+ 1. Call `inspect_pr` first. Never judge a change you haven't fetched.
126
+ 2. Match your review to the complexity it reports:
127
+ - `trivial`: read the patches. If the diff does what the title says
128
+ and nothing looks risky, call `submit_review` with verdict
129
+ `approve`.
130
+ - `moderate`: read every patch. Approve only when you understand the
131
+ whole change and see no risk. Otherwise ask for a human review and
132
+ say which files worry you.
133
+ - `large`: call `submit_review` with verdict `request_human_review`
134
+ right away. Use the stats you already have to point the reviewer at
135
+ the biggest files; don't dig further.
136
+ 3. Never approve a draft. Point out anything surprising, even when you
137
+ approve.
138
+
139
+ End with one sentence: the verdict and why.
100
140
  ```
101
141
 
102
142
  Remove the demo echo tool:
@@ -105,79 +145,332 @@ Remove the demo echo tool:
105
145
  rm agent/tools/echo.ts
106
146
  ```
107
147
 
108
- ## Add a weather tool
148
+ ## Add a shared helper
149
+
150
+ Both tools need to split a PR URL into its parts. Shared code lives in
151
+ `agent/lib/`, which the framework never loads as tools.
152
+
153
+ Create `agent/lib/github.ts`:
154
+
155
+ ```ts
156
+ export interface PullRef {
157
+ owner: string;
158
+ repo: string;
159
+ number: number;
160
+ }
161
+
162
+ /** Split https://github.com/owner/repo/pull/123 into its parts. */
163
+ export function parsePullUrl(prUrl: string): PullRef {
164
+ const url = new URL(prUrl);
165
+ const [owner, repo, pulls, number] = url.pathname.split("/").filter(Boolean);
166
+ const parsed = Number.parseInt(number ?? "", 10);
167
+ if (pulls !== "pull" || owner === undefined || Number.isNaN(parsed)) {
168
+ throw new Error(`Not a pull request URL: ${prUrl}`);
169
+ }
170
+ return { owner, repo, number: parsed };
171
+ }
172
+ ```
173
+
174
+ ## Add the inspect tool
109
175
 
110
- Create `agent/tools/get_weather.ts`:
176
+ Create `agent/tools/inspect_pr.ts`:
111
177
 
112
178
  ```ts
113
179
  import { defineTool } from "@cursor/july/tools";
114
180
  import { z } from "zod";
181
+ import { parsePullUrl } from "../lib/github.js";
182
+
183
+ export type Complexity = "trivial" | "moderate" | "large";
184
+
185
+ /** Deterministic policy: the tool rates the change, not the model. */
186
+ function rateComplexity(linesChanged: number, changedFiles: number): Complexity {
187
+ if (linesChanged <= 25 && changedFiles <= 2) {
188
+ return "trivial";
189
+ }
190
+ if (linesChanged <= 400 && changedFiles <= 15) {
191
+ return "moderate";
192
+ }
193
+ return "large";
194
+ }
195
+
196
+ /** Keep one oversized file from flooding the model's context. */
197
+ function trimPatch(patch: string | undefined): string | undefined {
198
+ if (patch === undefined || patch.length <= 3000) {
199
+ return patch;
200
+ }
201
+ return `${patch.slice(0, 3000)}\n[... patch trimmed ...]`;
202
+ }
115
203
 
116
204
  export default defineTool({
117
- description: "Get simulated current weather for a city.",
205
+ description:
206
+ "Fetch a pull request's title, stats, and per-file patches, plus a deterministic complexity rating (trivial, moderate, or large). Call this before any review decision.",
118
207
  inputSchema: z.object({
119
- city: z.string().describe("City name, such as San Francisco"),
208
+ prUrl: z
209
+ .string()
210
+ .describe("Pull request URL: https://github.com/owner/repo/pull/123"),
120
211
  }),
121
- async execute({ city }) {
122
- const temperatureF = Math.round(Math.random() * (90 - 32) + 32);
123
-
212
+ async execute({ prUrl }, ctx) {
213
+ const { owner, repo, number } = parsePullUrl(prUrl);
214
+ const octokit = await ctx.host.github.getOctokit();
215
+ const { data: pr } = await octokit.rest.pulls.get({
216
+ owner,
217
+ repo,
218
+ pull_number: number,
219
+ });
220
+ const { data: files } = await octokit.rest.pulls.listFiles({
221
+ owner,
222
+ repo,
223
+ pull_number: number,
224
+ per_page: 100,
225
+ });
226
+
227
+ const complexity = rateComplexity(
228
+ pr.additions + pr.deletions,
229
+ pr.changed_files
230
+ );
124
231
  return {
125
- city,
126
- temperatureF,
127
- conditions: "sunny",
232
+ title: pr.title,
233
+ author: pr.user?.login,
234
+ state: pr.state,
235
+ draft: pr.draft ?? false,
236
+ additions: pr.additions,
237
+ deletions: pr.deletions,
238
+ changedFiles: pr.changed_files,
239
+ complexity,
240
+ files: files.map((file) => ({
241
+ path: file.filename,
242
+ additions: file.additions,
243
+ deletions: file.deletions,
244
+ // Large changes get a stats-only skim; a human reads the code.
245
+ ...(complexity === "large" ? {} : { patch: trimPatch(file.patch) }),
246
+ })),
128
247
  };
129
248
  },
130
249
  });
131
250
  ```
132
251
 
133
- The file adds one tool named `get_weather`:
252
+ The file adds one tool named `inspect_pr`:
134
253
 
135
254
  - `description` tells the model when to call it.
136
255
  - `inputSchema` defines and validates the arguments.
137
256
  - `execute` runs on the server and returns data to the model.
138
257
 
139
- This version uses simulated data so you can run it without another API
140
- key. Replace `execute` with a weather API when you're ready.
258
+ Two details carry the design. `rateComplexity` is the review policy,
259
+ and it lives in code: the model never decides what counts as a big
260
+ change. And `ctx.host.github` is the shared host GitHub client, so the
261
+ tool inherits whatever credential the host has (a token, `gh auth`, or
262
+ a GitHub App) without parsing any of it.
141
263
 
142
- ## Try the weather tool
264
+ ## Try the inspect tool
143
265
 
144
- Call the tool directly first:
266
+ Call the tool directly first, on a real merged pull request:
145
267
 
146
268
  ```bash
147
- agentkit call get_weather --dir . \
148
- --input '{"city":"San Francisco"}'
269
+ agentkit call inspect_pr --dir . \
270
+ --input '{"prUrl":"https://github.com/react/react/pull/35623"}'
271
+ ```
272
+
273
+ `call` validates the input and runs `execute` without a model turn.
274
+ This PR is a one-character typo fix, so the result comes back rated
275
+ `trivial` with the whole patch inline:
276
+
277
+ ```json
278
+ {
279
+ "title": "Fix typo: accomodate -> accommodate",
280
+ "additions": 1,
281
+ "deletions": 1,
282
+ "changedFiles": 1,
283
+ "complexity": "trivial",
284
+ "files": [{ "path": "compiler/packages/...", "patch": "@@ -1315,7 ..." }]
285
+ }
286
+ ```
287
+
288
+ Now call it on the PR that added `experimental_useEvent` to React:
289
+ 1,027 additions across 26 files.
290
+
291
+ ```bash
292
+ agentkit call inspect_pr --dir . \
293
+ --input '{"prUrl":"https://github.com/react/react/pull/25229"}'
294
+ ```
295
+
296
+ The rating flips to `large` and the patches disappear from the result.
297
+ The policy in the tool decides how much the model gets to see, before
298
+ any model turn spends a token on it.
299
+
300
+ ## Add the review tool
301
+
302
+ The approver needs a way to act on its verdict. Create
303
+ `agent/tools/submit_review.ts`:
304
+
305
+ ```ts
306
+ import { defineTool } from "@cursor/july/tools";
307
+ import { z } from "zod";
308
+ import { parsePullUrl } from "../lib/github.js";
309
+
310
+ export default defineTool({
311
+ description:
312
+ "Post the review decision to GitHub: approve the pull request, or comment asking for a human review.",
313
+ inputSchema: z.object({
314
+ prUrl: z
315
+ .string()
316
+ .describe("Pull request URL: https://github.com/owner/repo/pull/123"),
317
+ verdict: z.enum(["approve", "request_human_review"]),
318
+ summary: z
319
+ .string()
320
+ .describe("One or two sentences explaining the verdict."),
321
+ }),
322
+ async execute({ prUrl, verdict, summary }, ctx) {
323
+ const { owner, repo, number } = parsePullUrl(prUrl);
324
+ const review =
325
+ verdict === "approve"
326
+ ? { event: "APPROVE" as const, body: `PR approver: ${summary}` }
327
+ : {
328
+ event: "COMMENT" as const,
329
+ body: `PR approver: this change needs a human review. ${summary}`,
330
+ };
331
+
332
+ const octokit = await ctx.host.github.getOctokit();
333
+ await octokit.rest.pulls.createReview({
334
+ owner,
335
+ repo,
336
+ pull_number: number,
337
+ event: review.event,
338
+ body: review.body,
339
+ });
340
+ return { posted: true, ...review };
341
+ },
342
+ });
149
343
  ```
150
344
 
151
- `call` validates the input and runs `execute` without a model turn. If
152
- the result looks right, ask the agent:
345
+ The tool posts a real review: an APPROVE when the agent approves, a
346
+ comment asking for a human otherwise. Two GitHub rules shape how you
347
+ test it. Your credential needs write access to the repo it reviews,
348
+ and GitHub rejects approving your own pull request, so hand the agent
349
+ a teammate's PR rather than one you authored. When a post fails, the
350
+ tool call reports the GitHub error to the model and the turn keeps
351
+ going.
352
+
353
+ Want a person to sign off before the review lands? Set
354
+ `needsApproval: true` on the tool and the call parks until someone
355
+ approves it from the playground or Slack.
356
+ [Human-in-the-loop approvals](./guides/human-in-the-loop.md) shows the
357
+ flow.
358
+
359
+ ## Review a pull request
360
+
361
+ Run the whole loop on a pull request your credential can review. A
362
+ teammate's open PR is the right pick: write access to the repo, and
363
+ not authored by you.
153
364
 
154
365
  ```bash
155
366
  agentkit run --dir . \
156
- --message "What's the weather in San Francisco?"
367
+ --message "Review https://github.com/acme/checkout/pull/42"
157
368
  ```
158
369
 
159
- The agent calls `get_weather`, receives the result, and uses it in the
160
- final reply. agentkit runs the tool loop for you.
370
+ The trajectory shows two tool calls. The agent inspects the PR, reads
371
+ the patches, and submits its verdict. A small, clean change gets an
372
+ APPROVE review on the spot, with a one-line summary of what it checked.
373
+ A large one gets a comment asking for a human review, pointing at the
374
+ files a reviewer should start with. Same instructions, different
375
+ behavior, because the policy in the tool decided how much the model got
376
+ to see.
161
377
 
162
- ## Open the playground
378
+ Open the PR on GitHub: the review is on the timeline, posted by
379
+ whatever identity your credential belongs to.
380
+
381
+ ## Wake it from GitHub
163
382
 
164
- Start the development server:
383
+ A reviewer you have to prompt is only half useful. Give the agent a
384
+ GitHub channel so pull requests wake it. Create
385
+ `agent/channels/github.ts`:
386
+
387
+ ```ts
388
+ import {
389
+ defaultGitHubAuth,
390
+ githubChannel,
391
+ } from "@cursor/july/channels/github";
392
+
393
+ const REVIEW_ACTIONS = new Set(["opened", "reopened", "ready_for_review"]);
394
+
395
+ export default githubChannel({
396
+ botName: "pr-approver",
397
+ webhookEvents: ["pull_request"],
398
+ // submit_review owns every GitHub write. Without these flags the channel
399
+ // also posts chat replies and reactions to the PR when the token allows it.
400
+ deliverReplies: false,
401
+ progress: { reactions: false },
402
+ onPullRequest: (ctx, pr) => {
403
+ if (!REVIEW_ACTIONS.has(pr.action) || pr.draft) {
404
+ return null;
405
+ }
406
+ return {
407
+ auth: defaultGitHubAuth(ctx),
408
+ title: `Review ${ctx.repository.fullName}#${pr.number}`,
409
+ context: [
410
+ "",
411
+ `Review ${pr.url}. Inspect it first, then submit your verdict with submit_review.`,
412
+ ],
413
+ };
414
+ },
415
+ });
416
+ ```
417
+
418
+ The channel mounts `POST /v1/channels/github` and dispatches on the
419
+ `pull_request` events you declared. Opened, reopened, and undrafted PRs
420
+ start a model turn; everything else returns `null` and is skipped.
421
+
422
+ Serve the agent, then replay a real PR at it from a second terminal.
423
+ `replay` reads the PR through `gh api`, synthesizes a GitHub-shaped
424
+ webhook delivery, and POSTs it to the channel. No repo admin, no
425
+ tunnel:
165
426
 
166
427
  ```bash
167
- agentkit serve --dir . --dev
428
+ agentkit dev
429
+ # second terminal:
430
+ agentkit github replay https://github.com/acme/checkout/pull/42 \
431
+ --dir . --action opened
168
432
  ```
169
433
 
170
- Open the playground URL printed in the terminal. Ask the same weather
171
- question. The playground streams the reply and shows the tool arguments
172
- and result inline.
434
+ The replay prints the delivery, and the serve terminal shows the wake:
435
+
436
+ ```text
437
+ [agentkit] replaying acme/checkout#42 (pull_request) → 1 channel
438
+ [agentkit] pull_request.opened → pr-approver/github 200
439
+ ```
440
+
441
+ The agent runs the same inspect-then-submit loop, unprompted this time.
442
+ Replay the same PR again and the channel resumes that PR's session
443
+ instead of starting a new one: each pull request keeps one running
444
+ conversation.
445
+
446
+ ## Open the playground
447
+
448
+ Keep `agentkit dev` running and open the playground URL it printed. The
449
+ webhook session is in the session list, titled
450
+ `Review acme/checkout#42`, with the trigger message, both tool calls,
451
+ and the verdict laid out. Start a new chat there and ask for another
452
+ review to watch a turn stream live.
453
+
454
+ ## Go live
455
+
456
+ Replay is for development. For real deliveries, serve with
457
+ `--cursor-events --repo owner/repo` to pull events for repositories
458
+ connected to Cursor with no public URL, or run
459
+ `agentkit github forward` to relay webhooks to your dev server. The
460
+ [GitHub guide](./guides/github.md) compares the options. In production,
461
+ give the host GitHub App credentials so reviews post as your app's bot
462
+ identity instead of a personal account.
173
463
 
174
464
  ## Where to go next
175
465
 
176
- - [Tools](./reference/tools.md): add more typed capabilities, like
177
- replacing the simulated weather tool with live Open-Meteo data
178
- - [Evals](./evals.md): turn this weather question into a regression
179
- check
180
- - [Channels](./reference/channels.md): expose the agent through HTTP,
181
- Slack, or another webhook
466
+ - [`examples/approval-buddy`](../examples/approval-buddy/): the
467
+ production-shaped sibling, with commit statuses, review subagents,
468
+ and a deterministic stamp policy
469
+ - [Evals](./evals.md): freeze these two PRs as regression checks so
470
+ prompt changes can't flip a verdict
471
+ - [Tools](./reference/tools.md): more on typed tools, approvals, and
472
+ direct calls
473
+ - [GitHub](./guides/github.md): fixtures, forwarding, and pulling
474
+ events from Cursor
182
475
  - [Building agents with agents](./building-with-agents.md): have a
183
476
  coding agent extend the project for you
@@ -12,7 +12,9 @@ required argument is missing.
12
12
  | Command | Description |
13
13
  | ------------------------------------------------------- | ----------------------------------------------------- |
14
14
  | [`serve`](#serve) | Serve agents over HTTP (multi-agent by default) |
15
+ | [`dev`](#dev) | Local development: same as `serve --dev` |
15
16
  | [`chat`](#chat) | Talk to a running server from the terminal |
17
+ | [`resume`](#resume) | Reattach chat to an existing session id |
16
18
  | [`run`](#run) | One-shot turn on an ephemeral server; JSON trajectory |
17
19
  | [`call`](#call) | Call a server tool directly, no model turn |
18
20
  | [`eval`](#eval) | Run filesystem evals |
@@ -62,6 +64,23 @@ agent code.
62
64
  | `--no-docs` | Skip the documentation site at `/docs` (and its auto-build). |
63
65
  | `--cursor-events` | Pull SCM webhook events from Cursor's `/v0/scm-events` instead of receiving webhooks. Requires a signed-in host and `--repo` (repeatable). Offset state lives under `<state-root>/cursor-events/`. |
64
66
 
67
+ ## dev
68
+
69
+ `dev` is the local-development shortcut for `serve --dev`. Pass the
70
+ agent folder as a positional path, or run it from inside the project:
71
+
72
+ ```bash
73
+ agentkit dev
74
+ agentkit dev ./pr-approver
75
+ agentkit dev ./pr-approver --port 3000
76
+ ```
77
+
78
+ Same flags as [`serve`](#serve) (`--dir` still works if you prefer it).
79
+ Dev mode is always on: schedules and reminders wait for manual dispatch,
80
+ GitHub accepts unsigned loopback deliveries, and Vite HMR starts when
81
+ the toolchain is present. Prefer this over `serve --dev` while
82
+ iterating.
83
+
65
84
  ## chat
66
85
 
67
86
  `chat` talks to a running server from the terminal.
@@ -78,6 +97,21 @@ Streams the reply live: text, tool calls, and a per-turn usage footer.
78
97
  `{ ok, sessionId, continuationToken, trajectory }`. `--text` prints a
79
98
  compact dump, and `--no-color` forces plain output.
80
99
 
100
+ ## resume
101
+
102
+ `resume` reattaches the chat REPL to an existing session.
103
+
104
+ ```bash
105
+ agentkit resume ses_… --url http://127.0.0.1:3000/<slug>
106
+ agentkit resume ses_… --prod --team 1 --slug approval-buddy
107
+ agentkit resume ses_… --prod --message "continue from here"
108
+ ```
109
+
110
+ Same as `chat --session <id>`: looks up the continuation token via
111
+ `/v1/sessions` when `--continuation-token` is omitted, replays the
112
+ transcript, then accepts follow-ups. Accepts the same output flags as
113
+ [`chat`](#chat) (`--json`, `--text`, `--no-color`).
114
+
81
115
  ## run
82
116
 
83
117
  `run` executes one turn on an ephemeral server and prints a JSON trajectory.
@@ -156,11 +190,25 @@ prints.
156
190
  `init` scaffolds a new project.
157
191
 
158
192
  ```bash
159
- agentkit init ./my-agent # scaffold package.json + agent/ + a demo tool
160
- agentkit init # no directory: print the setup guide
193
+ agentkit init ./my-agent # scaffold package.json, tsconfig.json, agent/ + a demo tool
194
+ agentkit init ./my-agent --json # machine-readable summary for tooling
195
+ agentkit init # no directory: print the setup guide
161
196
  ```
162
197
 
163
- Refuses to overwrite existing files.
198
+ The scaffold summary lists each file as `create` or `exist` (existing
199
+ files are left alone) and the project folder path, then runs
200
+ `npm install` so `@cursor/july` resolves for `dev` / `run`. On a TTY,
201
+ on a TTY, `init` asks before installing (or updating) the package
202
+ coding-agent skills into `~/.cursor/skills/agentkit/`, always overwriting
203
+ with the version from the installed package (skipped for `--json` /
204
+ non-interactive hosts). When the host has no Cursor credential yet,
205
+ `init` runs `agentkit login` and waits for the browser sign-in to
206
+ finish, then prints next steps: `cd` into the project (when needed),
207
+ `agentkit login` (when still unsigned), and `agentkit dev`. `--json`
208
+ still installs dependencies but never blocks on login or skill install;
209
+ it prints
210
+ `{ ok, directory, created, skipped, installed, installError, next }`
211
+ (with `login` in `next` when unsigned).
164
212
 
165
213
  ## info
166
214
 
@@ -43,16 +43,18 @@ covers controlling that.
43
43
  ## Best Practices
44
44
 
45
45
  Keep them a few lines: identity, when to use which tool, output shape.
46
- The [quickstart weather agent](../quickstart.md) is the pattern:
46
+ The [quickstart PR approver](../quickstart.md) is the pattern:
47
47
 
48
48
  ```md
49
- # Weather agent
49
+ # PR approver
50
50
 
51
- You are a concise weather assistant.
51
+ You review GitHub pull requests. Be specific and brief.
52
52
 
53
- - Use `get_weather` before answering questions about current weather.
54
- - Tell the user the weather data is simulated.
55
- - Keep replies to two sentences or fewer.
53
+ 1. Call `inspect_pr` first. Never judge a change you haven't fetched.
54
+ 2. Match your review to the complexity it reports.
55
+ 3. Never approve a draft.
56
+
57
+ End with one sentence: the verdict and why.
56
58
  ```
57
59
 
58
60
  - Name the tools and the decision rule ("use X before answering about
@@ -106,7 +106,7 @@ inputs again, and adds an eval for each improvement you keep.
106
106
 
107
107
  ## Related
108
108
 
109
- - [Build your first weather agent](./quickstart.md)
109
+ - [Build your first PR approver](./quickstart.md)
110
110
  - [Building agents with agents](./building-with-agents.md)
111
111
  - [Evals](./evals.md)
112
112
  - [Hillclimbing](./hillclimbing.md)