Appearance
Review prepared pull-request evidence
This GitHub-read-only reviewer uses host code to fetch the PR with gh and git, builds a trimmed pr/ evidence tree, then hands that tree to the model. The model reads the diff, loads a review skill, and returns at most three high-confidence findings.
Use this example when the host should control evidence collection and the model shouldn't browse or mutate the source repository.
Browse the current reviewer source.
Separate evidence preparation from review
The reviewer separates preparation from judgment:
- Host code owns GitHub and Git access.
- A server tool turns untrusted PR input into bounded workspace files.
- A custom channel seeds those files before the model starts.
- An on-demand skill defines the review procedure and output contract.
- The model returns chat text. No path posts a GitHub review.
This architecture gives the model a purpose-built evidence package instead of a checkout.
Follow a review
The custom HTTP path runs this sequence:
POST /v1/channels/review/receives a PR reference.- The handler calls
prepare_prwithout a model turn. - Host code reads PR metadata and the unified diff.
- It reuses a matching checkout, force-fetching the PR ref there when the commit is missing. Without a matching checkout, it uses a temporary bare cache.
- It creates
pr/MANIFEST.md,pr/meta.json,pr/diff.patch, and selected small files and rules. send({ workspaceFiles })creates the model session with that evidence.- The model reads the manifest and diff, then loads
pr-review. - The channel returns session and playground URLs while the review streams.
If a normal chat starts without evidence, the model can call prepare_pr mid-turn. That form writes the same files into the active session workspace.
Map the evidence-review files
| File | Purpose |
|---|---|
agent/agent.ts | Selects the local runtime and model. |
agent/instructions.md | Requires diff-first review and confines model work to pr/. |
agent/tools/prepare_pr.ts | Exposes host preparation as a typed server tool. |
agent/lib/prepare-pr.ts | Parses PR references, runs gh and git, and builds the evidence map. |
agent/channels/review.ts | Provides the loopback-only prepare-and-send HTTP route. |
agent/channels/slack.ts | Extracts PR references and prepares evidence for mentions and direct messages. |
agent/skills/pr-review.md | Sets finding limits, severities, and the machine-readable review format. |
agent/lib/log.ts | Writes timing logs for the host tools to stderr. |
agent/storage.ts | Persists sessions and events with cursorHostedStorage. |
evals/evals.config.ts | Caps eval run concurrency. |
evals/review/smoke.eval.ts | Seeds fake evidence and checks the review path without GitHub. |
There is no authored GitHub channel, MCP connection, subagent, schedule, hook, A/B experiment, approval, or custom storage.
Prepare the host
You need:
- Node 22.13 or newer.
- An agent-runtime credential for model turns and account-linked Slack.
ghandgitonPATH.ghaccess to the target PR.- Network access to GitHub and a writable temporary directory.
The preparer can prefer a configured local checkout. Its origin must match the target repository. Otherwise the reviewer uses its bare cache. It never checks out the PR into the serve host's working tree.
Validate the surface
bash
agent-sdk validate --dir examples/bugbot
agent-sdk info --dir examples/bugbot --jsonThe manifest should show one server tool, one skill, and two authored channels.
Inspect evidence without a model turn
Call the preparation tool directly:
bash
agent-sdk call prepare_pr \
--dir examples/bugbot \
--input '{"pr":"https://github.com/owner/repo/pull/123"}'Direct tool calls use a scratch workspace removed after the call. prepare_pr detects this path and returns the complete file map in its result. In a model session, it writes the files and returns a smaller summary.
The evidence builder applies explicit limits:
| Evidence | Limit |
|---|---|
| Post-change file | 12,000 characters |
| One rule file | 8,000 characters |
| Combined rules | 12,000 characters |
| PR body in metadata | 2,000 characters |
Large files remain visible in diff.patch. The manifest records which full files or rules were omitted.
The per-file limits aren't an aggregate context cap. Every changed file below 12,000 characters can be included. The diff command has a 12 MiB output buffer; a larger diff fails preparation instead of being truncated.
Run the HTTP review path
Start the server:
bash
agent-sdk dev examples/bugbotFrom another terminal:
bash
curl -s -X POST \
http://127.0.0.1:3000/bugbot/v1/channels/review/ \
-H 'content-type: application/json' \
-d '{"pr":"https://github.com/owner/repo/pull/123"}'The route returns status: "started", a continuation token, and session and playground URLs. Open the session URL to watch the model read the evidence and produce findings.
The channel declares localDevStrict(). Direct loopback callers can use it. Proxy-forwarding headers and non-loopback hosts are rejected.
Send a follow-up by passing the returned key:
bash
curl -s -X POST \
http://127.0.0.1:3000/bugbot/v1/channels/review/ \
-H 'content-type: application/json' \
-d '{"pr":"owner/repo#123","key":"<continuation-token>"}'The follow-up resumes the session without fetching a new evidence tree.
Run the Slack path
The account-linked Slack channel handles review-bot mentions and direct messages:
Slack handlers don't receive the channel callTool helper. This example calls the shared preparePrReview host function, then returns workspaceFiles in the Slack message preparation result. The model sees the same evidence and prompt as the HTTP path.
If a message contains no PR reference, the handler asks for one. Thread follow-ups keep the same session.
See how the skill constrains review
pr-review.md tells the model to:
- read the manifest and unified diff first,
- open at most one supporting file or rules file when a hunk is ambiguous,
- avoid shell, network,
gh, andgit, - report no more than three findings,
- keep each description under 120 words, and
- emit the machine-readable review contract.
The root instructions set the evidence boundary. The skill holds the reusable review procedure. Keeping those roles separate lets another agent reuse the same skill with different intake channels.
Run the fixture-backed eval
bash
agent-sdk eval --dir examples/bugbot --list
agent-sdk eval --dir examples/bugbot review/smoke --jsonThe eval constructs a PreparedPrReview, seeds its file map through workspaceFiles, and checks for at least one read call with no shell call. It doesn't assert which evidence file was read or whether the skill loaded. It accepts either a formatted review or a clean result.
This case tests review behavior without GitHub credentials or network data. Add fixtures with reachable bugs when you need stricter location and severity checks.
Keep the side-effect boundary clear
The reviewer makes no remote GitHub writes. It doesn't author a GitHub channel and doesn't call a review API. Host preparation does write session evidence and force-update refs/pull/<N>/head in either its bare cache or a matching local checkout when the commit is missing. Every result ends with a note saying no GitHub review was posted.
If you add publishing later, keep it in a separate tool. This preserves a read-only preparation and review path safe to run in evals.
Reuse the evidence handoff
Use host-prepared workspaces when:
- external APIs should stay off the model's tool surface,
- context needs hard size limits,
- the model should inspect a snapshot instead of a live checkout, or
- several channels need the same preparation.
Return workspaceFiles from direct host preparation, write into ctx.workspaceDir for mid-turn recovery, and encode the reading order in both the manifest and a skill.