Coding agent
Hand a report to Cursor and get a pull request. Let the small ones merge themselves.
A report already carries what a developer needs to start: the element, the errors, the failed requests, the page. A coding agent can start from the same thing. Hand a report over and Cursor reads your repository, writes a fix and opens a pull request, with a link back to the report for whoever reviews it.
Each project has one agent. A report, or a whole review round, goes over as one run, and the agent opens one pull request, sometimes as a draft. Nothing merges unless the project turns that on, an admin names who it is on for, and the change turns out to be only the kinds of thing you said may merge; by default the agent opens pull requests and stops. Handing a report over works on every plan, Free included. Merging on its own is on the Team and Agency plans.
Keys, and where each one goes
Three keys are involved. Two are yours and go in different places; the third is ours.
| Key | Where | What for |
|---|---|---|
| Cursor API key | Settings › GitHub & coding agent, Cursor row. One per project. | Launching runs, and "Check again". cursor.com/dashboard → Integrations → User API Keys. |
| GitHub | Settings › GitHub & coding agent, GitHub row, above Cursor's. The GitHub App, installed on the repository. | The automatic merge, and learning that a pull request opened. See Connecting GitHub. |
| Reviewer key | Nowhere on your side. | The reviewer that reads each changed file before a merge is ours, one key for the whole service. Nothing to paste. |
What GitHub grants, on the project's repository and no other:
- Contents: write and Pull requests: write: needed for the automatic merge.
- Commit statuses: read and Checks: read: a failed check is named on the pull request the moment it fails, and a passing one lets the merge go.
- Deployments: read: which commit a preview's address serves (see Bugs found on a preview or on staging).
The webhook Cursor calls back on is registered with every launch and signed with a secret we generated when the agent was connected. There is nothing to configure for it, and no webhook to set up in Cursor.
Connect an agent
In the project's Settings › GitHub & coding agent, on the Cursor row below GitHub's:
- Repository: the one this site is built from,
owner/repoor its URL. Once GitHub is connected with a repository, the row shows that one instead of asking, and you change it on GitHub's row. - Cursor API key: from cursor.com/dashboard → Integrations → User API Keys. It is stored and never shown again. The page says when it was pasted, and if Cursor refuses the key, the page names it by that date. Leave the box blank on a later save and the saved key stays.
- Branch and model are optional. Without them the agent uses the repository's default branch and Cursor's default model.
There is one agent per project because a project is one codebase. Connecting a second provider would replace the first.
Hand a report over
Press Hand to Cursor on a report, or on an inbox row that has not been tried yet. Cursor bills each run, so the button asks first, and there is a limit of ten an hour per project. The report shows the run as it goes: working, finished with a pull request, or what went wrong.
We do not poll Cursor. A run's status changes when Cursor calls back, which it does when the agent finishes or fails. After an hour with no word, the report says nobody has heard from the run, and Check again asks Cursor once (sixty an hour per project, from a separate budget so a check never spends a launch). A run that finished without naming a pull request offers Check again too. The press asks Cursor, and GitHub when it is connected, and says so when neither has one yet.
Clients cannot hand a report over. The button spends the project's money on the project's repository, so it is for admins and members.
A whole review at once
A review round goes over as one run. Open the round and press Hand to Cursor there. Every finding in it goes into one prompt, and the agent opens one pull request that says what it did about each, including the ones it could not fix. A round sent to a tracker works the same way, as one ticket for all its findings.
A finding inside a round has no button of its own, and its page points at the round instead. Two presses would mean two bills and two pull requests for work reported in one sitting.
From the widget
A team member reviewing their own site, signed in through Review on the project's Inbox or On the team? Sign in in the widget, sees a switch in the form: Hand this round to the coding agent when it is finished. Leave it on and pressing Finish sends the round to the team as one ticket and to the agent as one run. Visitors never see the switch. The server does not take the widget's word for any of it, and checks the origin, who is asking, which project the round belongs to, whether an agent is connected, and the launch budget.
Bugs found on a preview or on staging
A bug seen on a pull request's preview often exists only in that pull request, and an agent starting from your default branch cannot find it. So when a report is handed over, we find the commit the page was built from, and the agent starts from that commit's branch.
There is usually nothing to set up. We look the page's address up in what your host already tells GitHub: the deployments it reports (Vercel and Netlify do), and the preview link its app posts on each pull request, as a comment or in its check (Vercel's "Visit Preview", Netlify's deploy preview, Cloudflare's preview URL). Only a comment written by an app counts, not one a person pasted, and your site's own address is never looked up.
For a host that tells GitHub nothing, tell the tag which commit the page was built from:
<script async src="https://brokenhere.com/w.js" data-wq-key="wq_…" data-wq-commit="COMMIT"></script>Fill COMMIT at build time from the variable your host or CI already has, for
example VERCEL_GIT_COMMIT_SHA on Vercel, COMMIT_REF on Netlify, or
CF_PAGES_COMMIT_SHA on Cloudflare Pages. The setup prompt under Setup
in the project's settings asks your coding agent to do this for you.
The tag's commit wins when there is one. Either way, we ask GitHub where that commit is, and never take the page's word for a branch:
| The page was built from | The agent starts from | Its pull request goes into |
|---|---|---|
| An open pull request's branch (a preview) | that branch | that branch |
| The tip of another branch, such as staging | that branch | that branch |
| Your default branch, now or earlier | your usual branch | your usual branch |
| A commit your repository does not have | your usual branch | your usual branch |
A fix for a preview's branch is a suggestion to that pull request, so it never merges on its own. The person working on that branch decides whether to take it. The report shows the commit, and the agent panel says which branch the run started from and why. Pull requests from forks are never used.
Letting small fixes merge themselves
Most of what an agent fixes from a report is small: a wrong word, a button label, a colour, a margin. Reviewing those by hand is the slow part. Each project has one switch for it, which only an admin can change, in its Settings › Auto-merge: Merge the agent's trivial fixes on this project without waiting for a review. The switch is per project because a marketing site can take a wording fix unattended when the billing app in the same workspace cannot. The same section lists what is still missing before anything can merge, with a link from each line to where it is fixed, and shows the last pull request that was reviewed.
Automatic merging is on the Team and Agency plans. On Free the switch cannot be turned on, and every pull request the agent opens waits for a person; handing reports to the agent works the same on every plan. A workspace that goes back to Free keeps its switches and its policy, but nothing merges on its own until it is on a paid plan again, and the report or round says why.
The switch says the project allows it. An admin then decides who it is allowed for, per person and once for every project. In Who may auto-merge, at the bottom of a project's Settings › Auto-merge, they tick Fixes may merge on their own beside each admin or member. Nobody is ticked to start with, so turning the switch on grants nothing until someone is named. A client's runs never merge, and there is no box to tick for one.
What has to be true before anything merges
Five things are checked, in this order, and each one that is not true leaves the pull request open with a sentence on the report saying which:
- The project's switch, under its Auto-merge settings, is on, and the workspace is on the Team or Agency plan.
- The run was started by an admin or member an admin has ticked. A client's run never qualifies, and neither does a run with no person behind it.
- GitHub is connected, with the permissions above, and a repository is chosen under GitHub & coding agent.
- The pull request is on the repository chosen there and on the one the agent was pointed at (the two have to be the same), comes from a branch of it rather than a fork, and targets the branch it was pointed at, and nowhere else.
- GitHub says it can merge: open, no conflicts, every required check green.
Then the diff is checked before the reviewer sees it. A pull request is left for a person, without further review, when it touches any of these:
- CI configuration or a hook, a Dockerfile, a shell script, an env file, a
package manager's settings, install hook or plugins, editor or dev container
settings, a submodule,
vercel.jsonornetlify.toml - a path you protect
- a manifest or lockfile, unless you trust dependency changes
- a lockfile that names a package source its old lines did not (a new host, a different package on the same registry, a different repository, a local path)
- a binary
- a file added, deleted, moved or copied
- more than twenty-five files, or more lines than you allow
File names are matched ignoring case.
What is left goes file by file to the reviewer, which answers three questions about each file with a probability: which one kind of change it is (wording, styling, documentation, markup, tests, dependency versions, or something else), whether it could change what the program does, and whether it adds anything from outside. A file counts as its kind only at 0.9 confidence or better, with no more than 0.2 on either of the other two questions. Tests and dependency versions are not held to the behaviour number, since they change what runs by definition. A lockfile is not held to the outside number, since it names a URL on nearly every line; its sources were already checked against its old lines above, and a lockfile that names a new one is a person's. A manifest is held to the outside number, so a version swapped for a URL or a git repository is a person's too. These thresholds are fixed, and there is no setting for them. Anything under them is "something else", and something else is always a person's.
Last, each file's kind is checked against your policy below. If every file is a kind you ticked, the pull request is squash-merged; if not, it is left with a comment saying which file needs eyes.
Drafts, and checks that are still running
Cursor sometimes opens the pull request as a draft. Which ones is Cursor's call, and there is no setting for it. A draft is reviewed like any other pull request and taken out of draft only after the reviewer and GitHub have both said yes, just before the merge. A pull request left for a person stays a draft, which is a reasonable signal that nobody has looked at it.
The review starts seconds after the pull request opens, which is minutes before a preview deploy has built. When the reviewer approves a change whose checks are still running, the report says it is waiting for them, and GitHub tells us the moment they finish: green, it merges then; a check that fails leaves the pull request for a person, and the comment names it. A check still running after six hours leaves it for a person too, with "merge it once it is green".
The merge names the exact commit the reviewer read, so anything pushed to the branch during the review or the wait leaves the pull request for a person rather than being merged unread.
Choosing what may merge
The policy belongs to each project, under its Settings › Auto-merge, in What may merge: a documentation site and a checkout do not trust the same kinds of change. Three settings share one Save:
- What may merge on its own: the kinds of change you trust. The reviewer names every file as exactly one kind, and the pull request merges only when every file is a kind you ticked. Wording, styling and documentation are on to start with; markup (structure with no logic), tests and dependency versions are there for teams that want them. Anything that is none of these (logic, data, configuration) is always a person's, whatever is ticked.
- Never merge a change to: paths or patterns of your own, one per line
from the repository root, such as
src/payments/**orconfig/*.json. A line protects what it names and everything under it, sosrc/paymentsorapps/*/billingcovers the whole folder. A pull request touching one is left for a person before the reviewer even reads it. Your lines add to what is never merged whatever you write: workflows, CI and hooks, Dockerfiles, shell scripts, env files, package registry settings. A manifest or lockfile counts as a dependency change and needs that kind ticked, and a lockfile that names a package source its old lines did not is a person's even then. - At most this many changed lines: added and deleted together, across the pull request. The limit starts at 400; past it a person reads the pull request. Twenty-five files is the ceiling either way, and a file added, deleted, moved or copied, or a binary, is never merged this way.
The policy is read when the pull request comes back, not when the agent is sent, so tightening it while a run is out applies to that run. Turning the switch off, or unticking the person, while an agent is out means the pull request it comes back with waits for a person.
Every way it ends, and where you see it
A run ends in one of these ways: still working, finished with a pull request,
finished with nothing to show, stopped with an error, or a launch that never
started (Cursor refused the key, could not find the repository, or could not
be reached). Each has a sentence under Coding agent on the report or the
round, and an inbox row says agent running, pull request open or
agent failed where it would otherwise say "in Notion". A launch refused by
the budget leaves no run at all, and the page where it was pressed says so.
When the pull request has come back and the project's switch is on, the same panel gains one more line:
| On the report | What happened |
|---|---|
| Checking whether the pull request can merge on its own… | The review is running. |
| The review stopped before it finished… | The review was cut off before it recorded what it decided. Check again on the report takes it up again, reading the pull request afresh, or look at the pull request yourself. If automatic merging was switched off in the meantime, the press says so instead. |
| Merged automatically. | Every file was a kind you ticked, GitHub said clean, and it was squash-merged. |
| Left for a person to review. | Something in the diff, or a check, needs eyes. The sentence after it says which file or which check. |
| Not merged automatically. | One of the five things above was not true: the switch or the plan, the person, the token, the repository, or the pull request was not open. |
| Could not review the pull request. | The reviewer or GitHub could not be reached, or the token was refused. The pull request is still open; merge it by hand or hand the report over again. |
When the switch is off the panel says nothing about merging, so a project that never turned it on is never told what it would have done.
The same decision goes on the pull request as a comment, with a table of every file, the kind it was found to be, and why. The reason something merged, or did not, sits beside the code as well as here, and the comment links back to the report.
Connecting a tracker
Jira, GitHub Issues, GitLab, ClickUp, Asana, Trello, monday.com, and the help desks (Zendesk, Intercom, Freshdesk, HubSpot, Front, Crisp), each with a destination.
Ask from Claude, ChatGPT or Codex
Connect the AI assistant you already use, and ask the coding agent for changes to your site without opening GitHub.