diffcop 发布本地优先 AI 代码审查工具,支持 Claude Code 与 GitHub Action
BrianEstrada/diffcop
diffcop 是一个本地优先的 AI 代码审查工具,通过你已在用的编码智能体在终端审查分支,使用已有订阅而不消耗 API token,目前支持 Claude Code,计划支持 Pi、Codex 和 OpenCode。
An opinionated, local-first AI code reviewer that runs on the coding agent you already use.
diffcop reviews your branch from the terminal through an agent harness, using the subscription you already pay for, so a review doesn't have to cost you API tokens. It supports Claude Code today, and support for Pi, Codex and OpenCode is planned.
The agent reviews your diff with read-only tools, a second pass double-checks every finding, and the same review can run on every pull request as a GitHub Action.
Quick start
Requires Bun and Claude Code logged in
with your subscription. Where you can't log in, run claude setup-token to get a long-lived token
for your subscription and set it as CLAUDE_CODE_OAUTH_TOKEN. To pay per token instead, set
ANTHROPIC_API_KEY.
git clone https://github.com/BrianEstrada/diffcop.git cd diffcop bun install bun link # puts `diffcop` on your PATH (~/.bun/bin) cd ../your-repo diffcop review "review this code"
Usage
diffcop review "focus on error handling" diffcop review "review this code" --base origin/develop # default: origin/HEAD, then main diffcop review "review this code" --cwd ../other-repo diffcop review "quick pass" --effort low # faster, shallower review diffcop review "review this code" --reporter json | jq .findings
diffcop review --help lists every option.
diffcop warns when a diff is too big to review well (over 1,000 changed lines or 20 files, not
counting lockfiles) and suggests splitting it. Change the limits with --maxLines and
--maxFiles.
GitHub Action
The action reviews each pull request and keeps the result in a single PR comment.
Run claude setup-token to get a token for your Claude subscription and add it as a
CLAUDE_CODE_OAUTH_TOKEN repo secret, or add an ANTHROPIC_API_KEY secret to pay per token. Then
add this workflow:
# .github/workflows/review.yml name: Review on: pull_request: # edited covers a retargeted base; other edits are skipped below. types: [opened, synchronize, reopened, ready_for_review, edited] concurrency: # A title or body edit gets its own group so it can't cancel a running review. group: review-${{ github.event.action == 'edited' && !github.event.changes.base && github.run_id || github.event.pull_request.number }} cancel-in-progress: true permissions: contents: read pull-requests: write jobs: review: # Fork PRs don't get secrets, so there's nothing to authenticate with. if: ${{ !github.event.pull_request.draft && github.event.pull_request.head.repo.full_name == github.repository && (github.event.action != 'edited' || github.event.changes.base) }} runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # diffcop needs the merge base with the PR's base branch persist-credentials: false - uses: BrianEstrada/diffcop@main with: anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} claude-code-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
| Input | Default | Description |
|---|---|---|
anthropic-api-key |
Set this or claude-code-oauth-token. |
|
claude-code-oauth-token |
From claude setup-token, for Claude subscriptions. |
|
github-token |
github.token |
Reads the PR and posts the comment. |
prompt |
Review this pull request for bugs, security issues, and regressions. | What to ask the reviewer. |
effort |
high |
low to max. Empty uses Claude Code's default. |
debug |
false |
Also log the reviewer's tool calls and thinking time. |
The action installs Bun, Node and pnpm on the runner, so later steps in the same job see those versions.
How a review works
The first pass looks for bugs the diff introduced, plus a few nits, and on a PR checks that the description matches the code. A second, fresh session then tries to disprove each finding, and only what survives is reported.
The review opens with one headline:
- 🔴 N issues found: high or medium bugs the diff introduced.
- 🟡 Description doesn't match the diff: the PR claims something the code doesn't do.
- 🟡 Only nits: nothing serious.
- ✅ All good: nothing found.
Below it, collapsible sections list the findings, bugs that predate the diff, what verification dropped and why, and the files the reviewer read.
On a PR, the reviewer also sees the title, description, labels, comments and reviews, sanitized before they reach the prompt. It treats the description as the author's claims, not as proof.
Contributing
bun install also sets up the git hooks. Run bun run check (typecheck, lint, format, tests)
before you open a PR. CI runs the same check on every PR.
Commit messages follow Conventional Commits, e.g.
feat(cli): add --json flag. The commit-msg hook runs commitlint and rejects anything else.
来源:GitHub · github.com