A local-first AI code review assistant with a kanban-style PR inbox that helps you manage and conduct GitHub PR reviews with Claude.
Gavel transforms PR review from a chore into a streamlined workflow. It provides a PR Inbox that automatically tracks pull requests from your configured sources, then helps you review them with AI assistance.
The Workflow:
- Inbox — PRs from GitHub searches or Slack channels appear here
- Review — Select a PR, choose a review persona, get AI-generated comments
- Refine — Approve, reject, or chat with Claude to refine each comment
- Submit — Post approved comments to GitHub; PR moves to "Reviewed"
- Track — PRs with new commits move to "Needs Attention"; merged PRs auto-clear
Key Features:
- Kanban inbox — Four columns: Inbox, Reviewed, Needs Attention, Done
- Multiple PR sources — GitHub search queries and Slack channel monitoring
- Change detection — New commits on reviewed PRs trigger re-review prompts
- Local staging — Nothing posts until you explicitly approve and submit
- Session persistence — Quit mid-review and pick up where you left off
Before using Gavel, you need:
-
GitHub CLI (
gh) — for GitHub authentication and API access# macOS brew install gh # Then authenticate gh auth login
-
Claude Code CLI (
claude) — for AI analysis# Install from https://claude.ai/code # Then authenticate claude login
-
Slack User OAuth Token (optional) — for Slack channel monitoring
- Create a Slack app at https://api.slack.com/apps
- Add User Token Scopes:
channels:history,channels:read,groups:history,groups:read - Install to your workspace and copy the User OAuth Token (
xoxp-...) - Either set
SLACK_USER_TOKENenv var or enter the token in Gavel's source config
# Clone the repository
git clone https://github.com/cfstout/gavel.git
cd gavel
# Install dependencies
npm install
# Run in development mode
npm run dev
# Or build for production
npm run buildWhen you first launch Gavel, you'll see an empty inbox. Click "Add PR Source" to configure where to find PRs:
GitHub Search Sources:
review-requested:@me— PRs where you're requested as reviewerauthor:@me is:open— Your open PRsinvolves:@me— PRs you're involved inorg:mycompany is:pr is:open— All open PRs in an organization
Slack Channel Sources:
- Enter a channel name (e.g.,
code-reviews) or channel ID (e.g.,C09HBHLPK25) to monitor for PR links - Using a channel ID avoids extra API calls and is recommended for large workspaces
- Requires a Slack User OAuth Token (see Prerequisites)
| Column | Description |
|---|---|
| Inbox | New PRs from your sources |
| Reviewed | PRs you've submitted comments on |
| Needs Attention | PRs with new commits since your last review |
| Done | Merged/closed PRs (auto-clears after 24 hours) |
- Click "Review" on any PR card
- Select a review persona:
- General Review — Balanced code quality review
- Security Audit — Focus on vulnerabilities
- Performance Review — Efficiency and scalability
- Code Style — Readability and consistency
- Wait for Claude to analyze the diff
- For each AI comment:
- ✓ Approve — Mark for submission
- ✗ Reject — Discard the comment
- 💬 Refine — Chat with Claude to modify
- Click Submit to post approved comments
Click "Enter a PR manually" to review any PR not in your inbox:
- Format:
owner/repo#123 - Or paste a GitHub PR URL
- After submitting a review, the PR is automatically added to your inbox and moved to the "Reviewed" column for tracking
Create your own review personas by adding markdown files to your Gavel data directory:
- macOS:
~/Library/Application Support/gavel/personas/ - Linux:
~/.config/gavel/personas/ - Windows:
%APPDATA%/gavel/personas/
---
name: My Team's Standards
description: Review against our team's coding guidelines
---
# Review Instructions
Focus on:
- Our naming conventions (camelCase for functions, PascalCase for classes)
- Required error handling patterns
- Test coverage requirements
When commenting:
- Be constructive and specific
- Reference our style guide where applicablegavel/
├── electron/ # Electron main process
│ ├── main.ts # App entry point
│ ├── github.ts # GitHub CLI wrapper (fetch, search, post)
│ ├── claude.ts # Claude CLI wrapper
│ ├── personas.ts # Persona loading
│ ├── inbox.ts # Inbox state persistence
│ ├── polling.ts # Background polling orchestration
│ ├── slack.ts # Slack API integration
│ ├── ipc.ts # IPC handler registration
│ └── preload.ts # Renderer API exposure
├── src/
│ ├── renderer/ # React frontend
│ │ ├── components/ # UI components
│ │ │ ├── InboxScreen.tsx # Kanban inbox view
│ │ │ ├── KanbanColumn.tsx # Column component
│ │ │ ├── PRCard.tsx # PR card component
│ │ │ ├── SourceConfigModal.tsx # Source management
│ │ │ └── ... # Review components
│ │ ├── store/
│ │ │ ├── reviewStore.ts # Review session state
│ │ │ └── inboxStore.ts # Inbox state
│ │ └── styles/
│ │ ├── Inbox.css # Inbox styles
│ │ └── ...
│ └── shared/
│ └── types.ts # Shared TypeScript types
├── personas/ # Built-in review personas
└── package.json
# Run in development with hot reload
npm run dev
# Type check
npx tsc --noEmit
# Build for production
npm run build-
GitHub Integration — Uses
ghCLI for all GitHub operations. PR search, status checks, and comment posting all go through your authenticatedghsession. -
Polling — Background polling (default: 5 minutes) checks your configured sources for new PRs and monitors existing PRs for changes (new commits, merges).
-
Claude Integration — Uses
claudeCLI to analyze code diffs. Your Claude Code authentication is used—no API keys required. -
Slack Integration — When configured, calls the Slack API directly to fetch channel messages and extract GitHub PR URLs. Token stored securely via Electron's safeStorage.
-
Deduplication — PRs are identified by
owner/repo#number. If the same PR appears across multiple sources, it only shows once in your inbox. -
Local-First — All state is stored locally. Nothing is sent to external servers except GitHub (for PRs) and Claude (for analysis).
Run gh auth login and complete the authentication flow.
Install Claude Code from https://claude.ai/code and run claude login.
Either set the SLACK_USER_TOKEN environment variable or enter a token in Configure Sources > Slack Channel.
See Prerequisites for how to create a Slack app and get a token.
- Check that your source is enabled (Configure Sources > Active Sources)
- Verify your GitHub search query returns results:
gh search prs "your query" - For Slack sources, ensure a valid User OAuth Token is configured and the token has access to the channel
- Using a channel ID (e.g.,
C09HBHLPK25) instead of a channel name avoids rate limits on large workspaces
GitHub API limits apply. Gavel will automatically back off and retry. If persistent, try:
- Reducing the number of sources
- Increasing poll interval in settings
Ensure you have write access to the repository and the PR is still open.
MIT
