@cursor/july 0.1.43 → 0.1.45
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.
- package/AGENTS.md +1 -1
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +13 -5
- package/dist/channels/github/types.d.ts +8 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels.d.ts +17 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +31 -0
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.DsTLo2j1.js → app.fHnNXEJ6.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BMT0xM4I.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DoVfutcV.js → VPLocalSearchBox.Cf6ghfFY.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DtuVtKkc.js → theme.B_5-VLe8.js} +2 -2
- package/dist/docs/assets/guides_opentelemetry.md.Csn7ZI25.js +27 -0
- package/dist/docs/assets/guides_opentelemetry.md.Csn7ZI25.lean.js +1 -0
- package/dist/docs/assets/index.md.COeoSkcF.js +5 -0
- package/dist/docs/assets/index.md.COeoSkcF.lean.js +1 -0
- package/dist/docs/assets/{quickstart.md.rIbfahJM.js → quickstart.md.DZxBu44y.js} +18 -49
- package/dist/docs/assets/quickstart.md.DZxBu44y.lean.js +1 -0
- package/dist/docs/assets/{reference_agent-config.md.CRmkoxd6.js → reference_agent-config.md.XRpxctsA.js} +9 -4
- package/dist/docs/assets/{reference_agent-config.md.CRmkoxd6.lean.js → reference_agent-config.md.XRpxctsA.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.DqEqQpGn.js → reference_cli.md.BDmjPPAm.js} +2 -2
- package/dist/docs/assets/{reference_tools.md.lSrsTxYJ.js → reference_tools.md.kJfJAP2m.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/opentelemetry.html +12 -5
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +8 -28
- package/dist/docs/quickstart.html +24 -55
- package/dist/docs/reference/agent-config.html +11 -6
- package/dist/docs/reference/artifacts.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +6 -6
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +5 -5
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/templates/triage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/cli-ax.js +2 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +38 -7
- package/dist/internal/deploy-client.d.ts +8 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +5 -2
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +46 -9
- package/dist/internal/host-otel.d.ts +25 -0
- package/dist/internal/host-otel.d.ts.map +1 -0
- package/dist/internal/host-otel.js +162 -0
- package/dist/internal/init-project.js +10 -10
- package/dist/internal/otel/collector.d.ts +5 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +68 -27
- package/dist/internal/sdk-runner.d.ts +1 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +1 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +1 -0
- package/dist/internal/session-engine.d.ts +5 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +23 -5
- package/dist/playground/assets/index-CZH9EFvO.css +1 -0
- package/dist/playground/assets/{index-D-DIYQzw.js → index-Dces8BDp.js} +26 -26
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +81 -2
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +33 -106
- package/docs/guides/opentelemetry.md +30 -0
- package/docs/quickstart.md +89 -227
- package/docs/reference/agent-config.md +52 -0
- package/docs/reference/cli.md +2 -2
- package/docs/reference/tools.md +5 -4
- package/package.json +2 -2
- package/skills/otel/SKILL.md +20 -2
- package/src/channels/github/github-channel.ts +9 -0
- package/src/channels/github/types.ts +4 -0
- package/src/channels.ts +38 -0
- package/src/index.ts +1 -0
- package/src/internal/cli-ax.ts +2 -2
- package/src/internal/cli-deploy.ts +58 -3
- package/src/internal/deploy-client.ts +11 -0
- package/src/internal/discovery.ts +49 -0
- package/src/internal/host-otel.ts +252 -0
- package/src/internal/init-project.ts +10 -10
- package/src/internal/otel/collector.ts +135 -50
- package/src/internal/sdk-runner.ts +6 -0
- package/src/internal/server.ts +1 -0
- package/src/internal/session-engine.ts +32 -2
- package/src/types.ts +89 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.BZx4pmZL.js +0 -1
- package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.js +0 -20
- package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.lean.js +0 -1
- package/dist/docs/assets/index.md.CMc5FP7E.js +0 -25
- package/dist/docs/assets/index.md.CMc5FP7E.lean.js +0 -1
- package/dist/docs/assets/quickstart.md.rIbfahJM.lean.js +0 -1
- package/dist/playground/assets/index-DQTH622f.css +0 -1
- /package/dist/docs/assets/{reference_cli.md.DqEqQpGn.lean.js → reference_cli.md.BDmjPPAm.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.lSrsTxYJ.lean.js → reference_tools.md.kJfJAP2m.lean.js} +0 -0
package/docs/quickstart.md
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Build your first PR
|
|
3
|
-
description: "Create an agent that reviews pull requests by complexity, approves
|
|
2
|
+
title: "Build your first PR reviewer"
|
|
3
|
+
description: "Create an agent that reviews pull requests by complexity, approves safe changes, and handles GitHub webhook events."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Build your first PR
|
|
6
|
+
# Build your first PR reviewer
|
|
7
7
|
|
|
8
|
-
Build
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
and watch a pull request wake it.
|
|
8
|
+
Build a GitHub PR reviewer that classifies changes as `trivial`,
|
|
9
|
+
`moderate`, or `large`, then approves safe changes or requests human
|
|
10
|
+
review. Add GitHub event handling so pull requests can trigger reviews.
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
typed tools, judgment lives in the model, and every decision is
|
|
15
|
-
inspectable in the playground.
|
|
12
|
+
## Getting started
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
- **Get started with an agent in Cursor:** follow
|
|
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).
|
|
17
|
+
- **Get started in the CLI:** continue below.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Prerequisites
|
|
20
20
|
|
|
21
21
|
- Node 22.13 or newer. Bun isn't supported.
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
sign-in. See [Run the CLI](/#run-the-cli) for other setups, such as a
|
|
26
|
-
monorepo source checkout.
|
|
22
|
+
- Run commands as `agent-sdk <command>`, or use
|
|
23
|
+
`npx @cursor/july <command>` when the CLI isn't on `PATH`. See
|
|
24
|
+
[Run the CLI](/#run-the-cli) for monorepo checkouts and other setups.
|
|
27
25
|
- A Cursor credential for model turns. Sign in once:
|
|
28
26
|
|
|
29
27
|
```bash
|
|
@@ -32,122 +30,33 @@ agent-sdk login
|
|
|
32
30
|
|
|
33
31
|
You can also set `CURSOR_API_KEY` instead of signing in.
|
|
34
32
|
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
automatically. Reading pull requests works on any public repo;
|
|
38
|
-
posting reviews needs write access to the repo you review.
|
|
33
|
+
- Authenticate with `gh auth login` or `GITHUB_TOKEN`. You can read
|
|
34
|
+
public pull requests. Posting reviews requires repository write access.
|
|
39
35
|
|
|
40
|
-
##
|
|
36
|
+
## Create and run the project
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
there:
|
|
38
|
+
Initialize the project and start the development server:
|
|
44
39
|
|
|
45
40
|
```bash
|
|
46
|
-
npx @cursor/july init ./pr-
|
|
47
|
-
cd pr-
|
|
48
|
-
agent-sdk dev # serve, and print the playground URL
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Open the playground URL and chat with the scaffold. Then, in a second
|
|
52
|
-
terminal (`dev` keeps running), run one turn from the command line:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
agent-sdk run --dir . --message "Introduce yourself in one sentence."
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
That's the whole loop: files become an agent, `dev` serves it, and
|
|
59
|
-
`run` exercises it. The rest of this page turns that scaffold into a
|
|
60
|
-
real PR approver.
|
|
61
|
-
|
|
62
|
-
## Scaffolding Agents
|
|
63
|
-
|
|
64
|
-
Have Cursor read [`skills/create-agent/SKILL.md`](../skills/create-agent/SKILL.md)
|
|
65
|
-
and describe what you want:
|
|
66
|
-
|
|
67
|
-
> Build me a PR approver for the playground. Start with one tool that
|
|
68
|
-
> inspects a pull request and guide me through the remaining decisions.
|
|
69
|
-
|
|
70
|
-
Cursor asks for missing choices, shows you the plan, then builds and
|
|
71
|
-
verifies the agent. Continue below to do the same by hand.
|
|
72
|
-
|
|
73
|
-
See [Scaffold an agent with Cursor](./scaffolding-agents.md) for the
|
|
74
|
-
full guided workflow.
|
|
75
|
-
|
|
76
|
-
## Create your project
|
|
77
|
-
|
|
78
|
-
Start with the built-in scaffold:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
npx @cursor/july init ./pr-approver
|
|
82
|
-
cd pr-approver
|
|
41
|
+
npx @cursor/july init ./sdk-pr-reviewer
|
|
42
|
+
cd sdk-pr-reviewer
|
|
83
43
|
agent-sdk dev
|
|
84
44
|
```
|
|
85
45
|
|
|
86
|
-
|
|
87
|
-
folders (each with a `.gitkeep`) so you can drop tools, channels, and
|
|
88
|
-
evals in place:
|
|
89
|
-
|
|
90
|
-
```text
|
|
91
|
-
pr-approver/
|
|
92
|
-
├── agent/
|
|
93
|
-
│ ├── agent.ts
|
|
94
|
-
│ ├── instructions.md
|
|
95
|
-
│ ├── tools/
|
|
96
|
-
│ │ └── echo.ts
|
|
97
|
-
│ ├── skills/
|
|
98
|
-
│ ├── mcp-connections/
|
|
99
|
-
│ ├── subagents/
|
|
100
|
-
│ ├── channels/
|
|
101
|
-
│ ├── hooks/
|
|
102
|
-
│ │ └── memory.ts
|
|
103
|
-
│ ├── ab/
|
|
104
|
-
│ ├── schedules/
|
|
105
|
-
│ ├── sandbox/workspace/
|
|
106
|
-
│ └── lib/
|
|
107
|
-
├── evals/
|
|
108
|
-
├── package.json
|
|
109
|
-
└── tsconfig.json
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
`agent.ts` holds the model and runtime settings. `instructions.md` is
|
|
113
|
-
the always-on system prompt, and the scaffold's version includes a
|
|
114
|
-
memory section that tells the agent how to consult its journal. Each
|
|
115
|
-
file under `agent/tools/` becomes a tool, and `agent/hooks/memory.ts`
|
|
116
|
-
journals every turn so future sessions can recall past work (delete it
|
|
117
|
-
to opt out). `tsconfig.json` type-checks the project (`npm run check`);
|
|
118
|
-
the framework runs your TypeScript directly, so nothing compiles.
|
|
119
|
-
|
|
120
|
-
`agent-sdk dev` blocks until you stop it. Keep it running and open a
|
|
121
|
-
second terminal for every other command on this page, starting with
|
|
122
|
-
these checks:
|
|
46
|
+
Keep `agent-sdk dev` running. In a second terminal, run:
|
|
123
47
|
|
|
124
48
|
```bash
|
|
125
|
-
agent-sdk
|
|
126
|
-
agent-sdk info --dir .
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
These commands inspect the project without starting a model turn.
|
|
130
|
-
|
|
131
|
-
## Run your agent
|
|
132
|
-
|
|
133
|
-
The scaffold already works. Run one turn from the terminal:
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
agent-sdk run --dir . \
|
|
137
|
-
--message "Introduce yourself in one sentence."
|
|
49
|
+
agent-sdk run --dir . --message "Introduce yourself in one sentence."
|
|
138
50
|
```
|
|
139
51
|
|
|
140
|
-
|
|
141
|
-
reply. It prints a JSON trajectory with the response, tool calls, and
|
|
142
|
-
token usage. It also writes an NDJSON trace under
|
|
143
|
-
`.agent-serve/traces/`.
|
|
52
|
+
Confirm the agent replies.
|
|
144
53
|
|
|
145
|
-
##
|
|
54
|
+
## Add review instructions
|
|
146
55
|
|
|
147
56
|
Replace `agent/instructions.md`:
|
|
148
57
|
|
|
149
58
|
```md
|
|
150
|
-
# PR
|
|
59
|
+
# PR reviewer
|
|
151
60
|
|
|
152
61
|
You review GitHub pull requests. Be specific and brief.
|
|
153
62
|
|
|
@@ -178,9 +87,6 @@ rm agent/tools/echo.ts
|
|
|
178
87
|
|
|
179
88
|
## Add a shared helper
|
|
180
89
|
|
|
181
|
-
Both tools need to split a PR URL into its parts. Shared code lives in
|
|
182
|
-
`agent/lib/`, which the framework never loads as tools.
|
|
183
|
-
|
|
184
90
|
Create `agent/lib/github.ts`:
|
|
185
91
|
|
|
186
92
|
```ts
|
|
@@ -213,7 +119,7 @@ import { parsePullUrl } from "../lib/github.js";
|
|
|
213
119
|
|
|
214
120
|
export type Complexity = "trivial" | "moderate" | "large";
|
|
215
121
|
|
|
216
|
-
/**
|
|
122
|
+
/** Rate complexity from fixed line and file-count thresholds. */
|
|
217
123
|
function rateComplexity(linesChanged: number, changedFiles: number): Complexity {
|
|
218
124
|
if (linesChanged <= 25 && changedFiles <= 2) {
|
|
219
125
|
return "trivial";
|
|
@@ -280,58 +186,30 @@ export default defineTool({
|
|
|
280
186
|
});
|
|
281
187
|
```
|
|
282
188
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- `description` tells the model when to call it.
|
|
286
|
-
- `inputSchema` defines and validates the arguments.
|
|
287
|
-
- `execute` runs on the server and returns data to the model.
|
|
189
|
+
## Verify complexity classification
|
|
288
190
|
|
|
289
|
-
|
|
290
|
-
and it lives in code: the model never decides what counts as a big
|
|
291
|
-
change. And `ctx.host.github` is the shared host GitHub client, so the
|
|
292
|
-
tool inherits whatever credential the host has (a token, `gh auth`, or
|
|
293
|
-
a GitHub App) without parsing any of it.
|
|
294
|
-
|
|
295
|
-
## Try the inspect tool
|
|
296
|
-
|
|
297
|
-
Call the tool directly first, on a real merged pull request:
|
|
191
|
+
Run `inspect_pr` against a small pull request:
|
|
298
192
|
|
|
299
193
|
```bash
|
|
300
194
|
agent-sdk call inspect_pr --dir . \
|
|
301
195
|
--input '{"prUrl":"https://github.com/facebook/react/pull/35623"}'
|
|
302
196
|
```
|
|
303
197
|
|
|
304
|
-
|
|
305
|
-
This PR is a one-character typo fix, so the result comes back rated
|
|
306
|
-
`trivial` with the whole patch inline:
|
|
307
|
-
|
|
308
|
-
```json
|
|
309
|
-
{
|
|
310
|
-
"title": "Fix typo: accomodate -> accommodate",
|
|
311
|
-
"additions": 1,
|
|
312
|
-
"deletions": 1,
|
|
313
|
-
"changedFiles": 1,
|
|
314
|
-
"complexity": "trivial",
|
|
315
|
-
"files": [{ "path": "compiler/packages/...", "patch": "@@ -1315,7 ..." }]
|
|
316
|
-
}
|
|
317
|
-
```
|
|
198
|
+
Confirm the result contains `"complexity": "trivial"`.
|
|
318
199
|
|
|
319
|
-
|
|
320
|
-
1,027 additions across 26 files.
|
|
200
|
+
Run it against a large pull request:
|
|
321
201
|
|
|
322
202
|
```bash
|
|
323
203
|
agent-sdk call inspect_pr --dir . \
|
|
324
204
|
--input '{"prUrl":"https://github.com/facebook/react/pull/25229"}'
|
|
325
205
|
```
|
|
326
206
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
any model turn spends a token on it.
|
|
207
|
+
Confirm the result contains `"complexity": "large"` and no `patch`
|
|
208
|
+
fields.
|
|
330
209
|
|
|
331
210
|
## Add the review tool
|
|
332
211
|
|
|
333
|
-
|
|
334
|
-
`agent/tools/submit_review.ts`:
|
|
212
|
+
Create `agent/tools/submit_review.ts` to post each verdict:
|
|
335
213
|
|
|
336
214
|
```ts
|
|
337
215
|
import { defineTool } from "@cursor/july/tools";
|
|
@@ -354,10 +232,10 @@ export default defineTool({
|
|
|
354
232
|
const { owner, repo, number } = parsePullUrl(prUrl);
|
|
355
233
|
const review =
|
|
356
234
|
verdict === "approve"
|
|
357
|
-
? { event: "APPROVE" as const, body: `PR
|
|
235
|
+
? { event: "APPROVE" as const, body: `PR reviewer: ${summary}` }
|
|
358
236
|
: {
|
|
359
237
|
event: "COMMENT" as const,
|
|
360
|
-
body: `PR
|
|
238
|
+
body: `PR reviewer: this change needs a human review. ${summary}`,
|
|
361
239
|
};
|
|
362
240
|
|
|
363
241
|
const octokit = await ctx.host.github.getOctokit();
|
|
@@ -373,47 +251,24 @@ export default defineTool({
|
|
|
373
251
|
});
|
|
374
252
|
```
|
|
375
253
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
test it. Your credential needs write access to the repo it reviews,
|
|
379
|
-
and GitHub rejects approving your own pull request, so hand the agent
|
|
380
|
-
a teammate's PR rather than one you authored. When a post fails, the
|
|
381
|
-
tool call reports the GitHub error to the model and the turn keeps
|
|
382
|
-
going.
|
|
383
|
-
|
|
384
|
-
Want a person to sign off before the review lands? Set
|
|
385
|
-
`needsApproval: true` on the tool and the call parks until someone
|
|
386
|
-
approves it from the playground or Slack.
|
|
387
|
-
[Human-in-the-loop approvals](./guides/human-in-the-loop.md) shows the
|
|
388
|
-
flow.
|
|
254
|
+
Use a GitHub credential with write access and a pull request you didn't
|
|
255
|
+
author.
|
|
389
256
|
|
|
390
257
|
## Review a pull request
|
|
391
258
|
|
|
392
|
-
|
|
393
|
-
teammate's open PR is the right pick: write access to the repo, and
|
|
394
|
-
not authored by you.
|
|
259
|
+
Review an open pull request:
|
|
395
260
|
|
|
396
261
|
```bash
|
|
397
262
|
agent-sdk run --dir . \
|
|
398
263
|
--message "Review https://github.com/acme/checkout/pull/42"
|
|
399
264
|
```
|
|
400
265
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
APPROVE review on the spot, with a one-line summary of what it checked.
|
|
404
|
-
A large one gets a comment asking for a human review, pointing at the
|
|
405
|
-
files a reviewer should start with. Same instructions, different
|
|
406
|
-
behavior, because the policy in the tool decided how much the model got
|
|
407
|
-
to see.
|
|
408
|
-
|
|
409
|
-
Open the PR on GitHub: the review is on the timeline, posted by
|
|
410
|
-
whatever identity your credential belongs to.
|
|
266
|
+
Confirm `inspect_pr` runs before `submit_review`, then verify the review
|
|
267
|
+
on GitHub.
|
|
411
268
|
|
|
412
|
-
##
|
|
269
|
+
## Trigger reviews from GitHub
|
|
413
270
|
|
|
414
|
-
|
|
415
|
-
GitHub channel so pull requests wake it. Create
|
|
416
|
-
`agent/channels/github.ts`:
|
|
271
|
+
Create `agent/channels/github.ts`:
|
|
417
272
|
|
|
418
273
|
```ts
|
|
419
274
|
import {
|
|
@@ -424,10 +279,8 @@ import {
|
|
|
424
279
|
const REVIEW_ACTIONS = new Set(["opened", "reopened", "ready_for_review"]);
|
|
425
280
|
|
|
426
281
|
export default githubChannel({
|
|
427
|
-
botName: "pr-
|
|
282
|
+
botName: "sdk-pr-reviewer",
|
|
428
283
|
webhookEvents: ["pull_request"],
|
|
429
|
-
// submit_review owns every GitHub write. Without these flags the channel
|
|
430
|
-
// also posts chat replies and reactions to the PR when the token allows it.
|
|
431
284
|
deliverReplies: false,
|
|
432
285
|
progress: { reactions: false },
|
|
433
286
|
onPullRequest: (ctx, pr) => {
|
|
@@ -446,57 +299,66 @@ export default githubChannel({
|
|
|
446
299
|
});
|
|
447
300
|
```
|
|
448
301
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
start a model turn; everything else returns `null` and is skipped.
|
|
452
|
-
|
|
453
|
-
Serve the agent, then replay a real PR at it from a second terminal.
|
|
454
|
-
`replay` reads the PR through `gh api`, synthesizes a GitHub-shaped
|
|
455
|
-
webhook delivery, and POSTs it to the channel. No repo admin, no
|
|
456
|
-
tunnel:
|
|
302
|
+
Keep `agent-sdk dev` running. In a second terminal, replay an open pull
|
|
303
|
+
request. Pull access is enough; repo admin isn't required:
|
|
457
304
|
|
|
458
305
|
```bash
|
|
459
|
-
agent-sdk dev
|
|
460
|
-
# second terminal:
|
|
461
306
|
agent-sdk github replay https://github.com/acme/checkout/pull/42 \
|
|
462
307
|
--dir . --action opened
|
|
463
308
|
```
|
|
464
309
|
|
|
465
|
-
|
|
310
|
+
Open the playground and confirm `Review acme/checkout#42` contains the
|
|
311
|
+
trigger, both tool calls, and the verdict.
|
|
466
312
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
313
|
+
## Run options
|
|
314
|
+
|
|
315
|
+
1. **CLI message**
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
agent-sdk run --dir . --message "Review https://github.com/acme/checkout/pull/42"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
2. **Local replay**
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
agent-sdk github replay https://github.com/acme/checkout/pull/42 \
|
|
325
|
+
--dir . --action opened
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
3. **Forward or `--cursor-events`**
|
|
329
|
+
|
|
330
|
+
Pull Cursor events:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
agent-sdk serve --dir . --cursor-events --repo owner/repo
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Forward GitHub webhooks:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
agent-sdk github forward --dir .
|
|
340
|
+
```
|
|
471
341
|
|
|
472
|
-
|
|
473
|
-
Replay the same PR again and the channel resumes that PR's session
|
|
474
|
-
instead of starting a new one: each pull request keeps one running
|
|
475
|
-
conversation.
|
|
342
|
+
Keep the local `dev` or `serve` process running.
|
|
476
343
|
|
|
477
|
-
|
|
344
|
+
4. **Hosted deployment**
|
|
478
345
|
|
|
479
|
-
|
|
480
|
-
webhook session is in the session list, titled
|
|
481
|
-
`Review acme/checkout#42`, with the trigger message, both tool calls,
|
|
482
|
-
and the verdict laid out. Start a new chat there and ask for another
|
|
483
|
-
review to watch a turn stream live.
|
|
346
|
+
Deploy once, set the GitHub App secrets, then redeploy:
|
|
484
347
|
|
|
485
|
-
|
|
348
|
+
```bash
|
|
349
|
+
agent-sdk deploy
|
|
350
|
+
agent-sdk secrets set sdk-pr-reviewer GITHUB_APP_ID GITHUB_APP_PRIVATE_KEY
|
|
351
|
+
agent-sdk deploy
|
|
352
|
+
```
|
|
486
353
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
connected to Cursor with no public URL, or run
|
|
490
|
-
`agent-sdk github forward` to relay webhooks to your dev server. The
|
|
491
|
-
[GitHub guide](./guides/github.md) compares the options. In production,
|
|
492
|
-
give the host GitHub App credentials so reviews post as your app's bot
|
|
493
|
-
identity instead of a personal account.
|
|
354
|
+
See [GitHub](./guides/github.md) for local event delivery and
|
|
355
|
+
[Deployment](./deployment.md) for hosting.
|
|
494
356
|
|
|
495
357
|
## Where to go next
|
|
496
358
|
|
|
497
|
-
- [`examples/approval-buddy`](../examples/approval-buddy/):
|
|
498
|
-
|
|
499
|
-
|
|
359
|
+
- [`examples/approval-buddy`](../examples/approval-buddy/): an example
|
|
360
|
+
with commit statuses, review subagents, and a deterministic stamp
|
|
361
|
+
policy
|
|
500
362
|
- [Evals](./evals.md): freeze these two PRs as regression checks so
|
|
501
363
|
prompt changes can't flip a verdict
|
|
502
364
|
- [Tools](./reference/tools.md): more on typed tools, approvals, and
|
|
@@ -44,6 +44,7 @@ export default defineAgent({
|
|
|
44
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
45
|
| `concurrency` | `{ maxRunningTurns? }` | Engine-wide turn admission limit. See [Concurrency](#concurrency). |
|
|
46
46
|
| `builtinTools` | `{ reminders? }` | Framework-provided model-facing tools, opted in per capability. See [Built-in tools](#built-in-tools). |
|
|
47
|
+
| `tools` | `ToolName[]` | Allowlist of built-in harness tools offered to the model. Unset = the model's full standard toolset. See [Allowlist built-in harness tools](#allowlist-built-in-harness-tools). |
|
|
47
48
|
|
|
48
49
|
## Choose a model
|
|
49
50
|
|
|
@@ -120,6 +121,57 @@ outside it (or runs with `--state-root` under `/tmp`). An agent that
|
|
|
120
121
|
*needs* a specific checkout's skills and rules points `cwd` inside that
|
|
121
122
|
checkout.
|
|
122
123
|
|
|
124
|
+
## Allowlist built-in harness tools
|
|
125
|
+
|
|
126
|
+
`tools` names which of the Cursor harness's built-in tools the model
|
|
127
|
+
is offered, riding the SDK's `AgentOptions.tools`. It is opt-in by
|
|
128
|
+
design: unset keeps the model's full standard toolset, and once set
|
|
129
|
+
the agent gets exactly what it names — nothing more. `[]` removes
|
|
130
|
+
every native built-in tool. There is deliberately no exclusion form:
|
|
131
|
+
an agent that restricts tools states what it keeps, so tools the
|
|
132
|
+
platform adds later stay off until someone opts in.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
export default defineAgent({
|
|
136
|
+
model: "composer-2.5",
|
|
137
|
+
// Read-only triage agent: search and read only.
|
|
138
|
+
// No shell, no edits, no subagents.
|
|
139
|
+
tools: ["read", "grep", "glob", "ls"],
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
One name is injected for you: **`"mcp"` is always granted alongside a
|
|
144
|
+
configured allowlist**. It is transport, not capability — this kit's
|
|
145
|
+
authored server tools reach the model over the SDK custom-tool MCP
|
|
146
|
+
path, so omitting it would silently strand `agent/tools/`. What MCP
|
|
147
|
+
actually exposes stays governed by the second layer: the tools you
|
|
148
|
+
author, the connections you declare, and the harness cwd's ambient
|
|
149
|
+
`.cursor` config. An agent that must not see a checkout's MCP servers
|
|
150
|
+
points `local.cwd` outside it (see [Local cwd](#local-cwd)), and
|
|
151
|
+
`local.sandbox` makes MCP tool calls fail closed.
|
|
152
|
+
|
|
153
|
+
The other names use the SDK's public tool vocabulary (`"shell"`,
|
|
154
|
+
`"read"`, `"edit"`, `"grep"`, `"glob"`, `"ls"`, `"task"`, ...);
|
|
155
|
+
unknown names fail the turn with a `ConfigurationError`. Two deserve
|
|
156
|
+
care: `"shell"` is a capability group that also grants shell stdin
|
|
157
|
+
writes — and is what `execution: "agent"` tool scripts run through,
|
|
158
|
+
so an allowlist without it strands them (discovery warns about that
|
|
159
|
+
combination). `"task"` gates subagents (which otherwise keep their
|
|
160
|
+
own curated toolsets).
|
|
161
|
+
|
|
162
|
+
The allowlist states runtime-agnostic intent, but the SDK cannot
|
|
163
|
+
enforce tool restrictions on cloud agents yet — and a restriction
|
|
164
|
+
must never silently not apply. A `runtime: "cloud"` agent that sets
|
|
165
|
+
`tools` fails at serve start with an error diagnostic, and a hybrid
|
|
166
|
+
agent's per-send cloud sessions are refused (the turn errors) rather
|
|
167
|
+
than run unrestricted. When the SDK lifts the limitation, the same
|
|
168
|
+
field will simply start applying to cloud turns.
|
|
169
|
+
|
|
170
|
+
Not a security boundary against the serve host: like `local.sandbox`,
|
|
171
|
+
the allowlist only shapes what the model can call; pair with
|
|
172
|
+
`sandbox: true` when the concern is untrusted input steering the
|
|
173
|
+
model.
|
|
174
|
+
|
|
123
175
|
## The `cloud` block
|
|
124
176
|
|
|
125
177
|
Cloud agent defaults forwarded to the Cursor SDK: `repos` (each
|
package/docs/reference/cli.md
CHANGED
|
@@ -141,8 +141,8 @@ agent folder as a positional path, or run it from inside the project:
|
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
143
|
agent-sdk dev
|
|
144
|
-
agent-sdk dev ./pr-
|
|
145
|
-
agent-sdk dev ./pr-
|
|
144
|
+
agent-sdk dev ./sdk-pr-reviewer
|
|
145
|
+
agent-sdk dev ./sdk-pr-reviewer --port 3000
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
`dev` accepts the same flags as [`serve`](#serve). You can use `--dir`
|
package/docs/reference/tools.md
CHANGED
|
@@ -82,10 +82,11 @@ export default defineTool({
|
|
|
82
82
|
`ctx.host` carries the shared host services: `host.mcp` (authored MCP
|
|
83
83
|
connections: `names()`, `listTools(name)`, `callTool(name, tool, args)`),
|
|
84
84
|
`host.github` and `host.slack` (shared platform clients), `host.kv` and
|
|
85
|
-
`host.files` (durable [storage](../storage.md)), `host.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
`host.files` (durable [storage](../storage.md)), `host.otel` (custom
|
|
86
|
+
metrics and session tags; see [OpenTelemetry](../guides/opentelemetry.md)),
|
|
87
|
+
`host.reminders` (per-session wakes, when attached), `host.evals`
|
|
88
|
+
(playground eval batches, when attached), and `host.slackNudges`
|
|
89
|
+
(Slack ask-dedupe helpers).
|
|
89
90
|
|
|
90
91
|
### Return values
|
|
91
92
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor/july",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
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": {
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
"node": ">=22.13"
|
|
216
216
|
},
|
|
217
217
|
"dependencies": {
|
|
218
|
-
"@cursor/sdk": "1.0.
|
|
218
|
+
"@cursor/sdk": "1.0.27",
|
|
219
219
|
"@modelcontextprotocol/sdk": "1.25.1",
|
|
220
220
|
"@octokit/auth-app": "^7.2.0",
|
|
221
221
|
"@octokit/rest": "^21.1.1",
|
package/skills/otel/SKILL.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: agentkit-otel
|
|
3
3
|
description: >-
|
|
4
4
|
Wire OpenTelemetry export for an Agent SDK agent (defineOtel, OTLP env,
|
|
5
|
-
traces/metrics/logs). Use when adding observability,
|
|
6
|
-
export,
|
|
5
|
+
traces/metrics/logs, ctx.host.otel). Use when adding observability,
|
|
6
|
+
Datadog/Grafana/OTLP export, session/turn/tool tracing, or custom metrics.
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Agent SDK OpenTelemetry (`defineOtel`)
|
|
@@ -61,6 +61,24 @@ Precedence: `serve({ otel })` over `agent/otel.ts` over env.
|
|
|
61
61
|
Prompt text, tool payloads, and failure text stay off the wire unless
|
|
62
62
|
those flags are set.
|
|
63
63
|
|
|
64
|
+
## Custom metrics (`ctx.host.otel`)
|
|
65
|
+
|
|
66
|
+
Always present. `increment` / `record` no-op without a meter.
|
|
67
|
+
`setAttributes` still tags the open session when a collector is
|
|
68
|
+
attached. Prefix names with team or agent. No custom spans. Reserved
|
|
69
|
+
metric names: `cursor.token.usage`, `cursor.tool.calls`,
|
|
70
|
+
`cursor.cost.usage`, `agent_sdk.session.count`,
|
|
71
|
+
`agent_sdk.turn.count`, `agent_sdk.subagent.count`,
|
|
72
|
+
`agent_sdk.http.duration`. Reserved attributes:
|
|
73
|
+
`cursor.conversation.id`, `agent_sdk.agent`, `agent_sdk.turn_id`,
|
|
74
|
+
`agent_sdk.framework`.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
ctx.host.otel.setAttributes({ "abc.ticket_id": "INC-123" });
|
|
78
|
+
ctx.host.otel.increment("abc.ticket.resolved");
|
|
79
|
+
ctx.host.otel.record("abc.approval.duration_ms", 1420);
|
|
80
|
+
```
|
|
81
|
+
|
|
64
82
|
## Attributes worth joining on
|
|
65
83
|
|
|
66
84
|
- `cursor.conversation.id` (session id)
|
|
@@ -137,6 +137,12 @@ const githubPullRequestPayloadSchema: z.ZodType<GitHubPullRequestPayload> =
|
|
|
137
137
|
}),
|
|
138
138
|
sender: senderSchema,
|
|
139
139
|
installation: installationSchema,
|
|
140
|
+
label: z
|
|
141
|
+
.object({
|
|
142
|
+
name: z.string().min(1),
|
|
143
|
+
})
|
|
144
|
+
.nullable()
|
|
145
|
+
.optional(),
|
|
140
146
|
});
|
|
141
147
|
|
|
142
148
|
/**
|
|
@@ -336,6 +342,9 @@ export function parseGitHubPullRequestEvent(args: {
|
|
|
336
342
|
...(payload.pull_request.user?.login === undefined
|
|
337
343
|
? {}
|
|
338
344
|
: { authorLogin: payload.pull_request.user.login }),
|
|
345
|
+
...(payload.label?.name === undefined
|
|
346
|
+
? {}
|
|
347
|
+
: { label: { name: payload.label.name } }),
|
|
339
348
|
};
|
|
340
349
|
return { ctx, pullRequest };
|
|
341
350
|
}
|
|
@@ -171,6 +171,8 @@ export type GitHubPullRequestPayload = {
|
|
|
171
171
|
type?: string;
|
|
172
172
|
} | null;
|
|
173
173
|
installation?: { id?: number } | null;
|
|
174
|
+
/** Present on `labeled` / `unlabeled` pull_request deliveries. */
|
|
175
|
+
label?: { name: string } | null;
|
|
174
176
|
};
|
|
175
177
|
|
|
176
178
|
/** Normalized `pull_request` event handed to {@link GitHubPullRequestHook}. */
|
|
@@ -188,6 +190,8 @@ export interface GitHubPullRequestEvent {
|
|
|
188
190
|
/** True when the PR was merged (from the webhook payload). */
|
|
189
191
|
merged: boolean;
|
|
190
192
|
authorLogin?: string;
|
|
193
|
+
/** Label added/removed on `labeled` / `unlabeled` actions. */
|
|
194
|
+
label?: { name: string };
|
|
191
195
|
}
|
|
192
196
|
|
|
193
197
|
/** Normalized `issues` event. */
|