samorev is a CLI-first review tool for GitHub Pull Requests and GitLab Merge Requests. The samorev review Bun CLI shares the provider-planning core and review prompt used by the Claude Code /review-mr command, so agents can invoke reviews non-interactively without forking the review system. The Claude Code prompt/command pack remains available for interactive use.
Operating samorev from a bot? Read
docs/bot-operation.md— the autonomous runbook (install, credential checklist, full command surface, verdict parsing) — anddocs/verdict-parsing.mdfor the machine-readable output grammar.
samorev has two surfaces that check different things. Pick the right one:
- Bun CLI —
samorev review(the surface a bot runs). A deterministic provider-fetch + review-gate. With--fetchit pulls PR/MR metadata, diff, comments, commits, and CI status and renders a PASS/FAIL report whose gate is CI status + draft state only. It does not run the AI review agents itself — the Security/Bugs/Tests/Guidelines/Docs rows are always0from the CLI. Seedocs/bot-operation.md. - Claude Code slash command —
/review-mr(interactive). Runs the 5–6 parallel LLM agents below for actual code analysis, plus CI, metadata, linked issue, and optional SOC2 checks. Requires a Claude Code session.
- Provider scope: Plans GitHub PR operations via
ghand GitLab MR operations viaglab, with a GitLab public REST API fallback for public MRs. - CLI review-gate (
samorev review --fetch): PASS/FAIL based on CI status and draft state, rendered as a postable Markdown report with a machine-readable metadata block. - Parallel multi-agent review (
/review-mrslash command): 5 specialized agents analyze code simultaneously, with optional repository-specific agents. - Confidence scoring (
/review-mr): rates each finding 0-10, filtering likely false positives. - Three-tier findings (
/review-mr): blocking, non-blocking, and potential issues. - Optional rules integration (
/review-mr): loads optional project-specific rules when a repository provides them. - Sqitch migration validation (
/review-mr, optional): ensures PostgreSQL schema changes have proper migrations.
| Agent | Model | Focus | Blocking | Scope |
|---|---|---|---|---|
| Security Reviewer | Opus | OWASP, secrets, injection | Yes | All repos |
| Bug Hunter | Opus | Runtime bugs, logic errors | Yes | All repos |
| Test Analyzer | Sonnet | Coverage, test quality | Configurable | All repos |
| Guidelines Checker | Sonnet | Project conventions, rules | No | All repos |
| Docs Reviewer | Sonnet | Documentation, comments | No | All repos |
| Sqitch Migration Checker | Opus | PostgreSQL migrations (Sqitch) | Yes | Optional |
- Bun (tested with 1.3.x) for the primary
samorevCLI. No Node runtime is required for the CLI. - GitHub CLI (
gh) authenticated when reviewing GitHub PRs:gh auth login
- GitLab CLI (
glab) authenticated when reviewing GitLab MRs (public GitLab MRs work without it via the public REST API fallback):glab auth login
- Python 3.11+ and jq — only for the Claude Code
/review-mrslash command and the Python compatibility tests; the Bun CLI does not need them. - Claude Code — only for the
/review-mrslash command (Surface B).
The Bun CLI authenticates through the gh/glab CLI token stores — it does
not read provider tokens from environment variables itself.
| What | How to set | Required for |
|---|---|---|
| GitHub auth | gh auth login (scopes: repo; add read:org for org-private, workflow for Actions logs) |
GitHub PR fetch + posting |
| GitLab auth | glab auth login (scope: api, or read_api for --no-comment only) |
Authenticated GitLab MR fetch + posting |
| GitLab public MRs | nothing — public REST API fallback | Read-only public GitLab MR fetch |
GITLAB_TOKEN / GITLAB_HOST |
env vars | Slash command only — lib/review_memory.py prior-context fetch |
Not needed to operate samorev: ANTHROPIC_API_KEY is used only by the
optional agent-quality test suite (pytest -m api), never by a review run.
OPENAI_API_KEY is not used anywhere. Never write tokens into committed files,
agent briefs, or posted comments — use the CLI auth stores and env-var names only.
Install from a checkout while the package is pre-release:
git clone https://github.com/Tanya301/samorev.git
cd samorev
bun install
bun run buildThe checkout command for agents is bun run samorev .... bun run build also writes the installable bin target at dist/cli.js.
See SPEC.md for the concise CLI contract, provider behavior, evidence standards, and acceptance criteria.
Primary CLI target for LLM-run reviews:
bun run samorev review <PR-or-MR> --no-comment --blockingFetch provider data and print an inline demo/report summary:
bun run samorev review <PR-or-MR> --no-comment --fetchExamples:
bun run samorev review https://github.com/example-org/example-repo/pull/123 --no-comment --blocking
bun run samorev review https://github.com/example-org/example-repo/pull/123 --no-comment --fetch
bun run samorev review https://gitlab.com/example-org/example-repo/-/merge_requests/123 --no-comment
bun run samorev review 123 --remote-url git@github.com:example-org/example-repo.git --no-comment --blockingThe Bun/TypeScript CLI is the primary interface for LLM agents. --fetch executes the provider metadata, diff, comments, commits, and CI fetches itself, then renders a readable PASS/FAIL review-gate comment with findings or a no-blockers statement plus title/state/draft status, diff size, comment count, commit count, CI summary, posted_by, and live_posting. Without --no-comment, the same gate comment is posted provider-native through authenticated gh or glab. GitHub uses gh. GitLab uses glab for authenticated posting and falls back to GitLab's public API only for no-comment public fetch reports.
Bot verdict parsing: a successful
--fetchexits0for both PASS and FAIL — the exit code reflects whether the fetch ran, not the verdict. Parse the report body:**Result: PASSED**means PASS, a### BLOCKING ISSUES (N)header means FAIL.--blockingonly recordsblocking=truein the output; it does not change the CLI exit code today (exit-on-findings is deferred — see SPEC §4). Full grammar:docs/verdict-parsing.md.
The installable CLI is the Bun package declared in package.json. The old Python package wrapper is retired; Python remains only for Claude Code slash-command compatibility helpers and legacy pytest coverage. .gitattributes marks those retained compatibility paths as Linguist-vendored so GitHub language presentation reflects the Bun/TypeScript-first CLI.
Use --smoke to verify provider planning and prompt wiring without running agents or posting:
bun run samorev review https://github.com/example-org/example-repo/pull/123 --no-comment --blocking --smokeUse --no-comment to print the summary locally without provider posting. If posting is requested and provider auth is missing, samorev exits non-zero with live_posting=blocked.
Install samorev globally so /review-mr works from any directory:
# Clone to Claude Code's config directory
git clone https://github.com/Tanya301/samorev.git ~/.claude/samorev
# Install the slash command
cd ~/.claude/samorev
bash scripts/install-claude-command.shTo update:
cd ~/.claude/samorev && git pullIf you prefer to install samorev as part of a specific project:
# Clone the repo
git clone https://github.com/Tanya301/samorev.gitThe /review-mr command will be available when running Claude Code from within the samorev directory or any project that includes samorev as a submodule.
The flags below apply to the slash command (Surface B). For the Bun CLI flags
and exit semantics, see the CLI installation section above
and docs/bot-operation.md.
# Review a GitLab MR by URL through Claude Code
/review-mr https://gitlab.com/example-org/example-repo/-/merge_requests/123
# Plan/review a GitHub PR by URL through Claude Code
/review-mr https://github.com/example-org/example-repo/pull/123
# Review by number (uses current repo context)
/review-mr 123
# Review without posting comment (output to terminal only)
/review-mr 123 --no-comment
# Exit with code 1 if blocking issues found (for CI integration)
/review-mr 123 --blockingGitHub PR reviews support provider parsing plus metadata, diff, comments, commits, CI status, report generation, and provider-native summary posting through gh pr comment. Use --no-comment for dry-run validation.
Flags:
--no-comment- Output review to terminal only, don't post to MR--blocking- Exit with code 1 if BLOCKING issues (CRITICAL/HIGH/MEDIUM) are found
The slash command delegates provider detection and command planning to lib/provider_planning.py. You can verify that wiring from a clean checkout without running a full AI review:
python lib/provider_planning.py https://github.com/example-org/example-repo/pull/123 --shell
python lib/provider_planning.py https://gitlab.com/example-org/example-repo/-/merge_requests/123 --shellThe slash command remains available for interactive Claude Code use and delegates to the same provider-planning helper as the CLI:
/review-mr https://github.com/example-org/example-repo/pull/123 --no-commentThe repository includes a .claude/settings.json file that configures safe default permissions for Claude Code:
- Allowed: Git, gh, glab, common dev tools (node, python, go, docker, psql, sqitch), file operations, web fetch
- Denied: Destructive commands (rm, sudo), network tools that bypass logging (curl, wget), access to secrets (.env*, secrets/**)
Note: Configuration file support is a planned feature and not yet implemented. See the project roadmap for updates.
# Example configuration (planned)
version: "1"
review:
blocking:
# CRITICAL, HIGH, and MEDIUM severity issues block merge
security: [critical, high, medium]
bugs: [critical, high, medium]
coverage_threshold: 80
non_blocking:
# LOW and INFO severity issues are suggestions
style: true
docs: true
languages:
- typescript
- python
- sql
ignore:
- "*.generated.ts"
- "migrations/*.sql"/review-mr invoked
│
▼
┌───────────────────┐
│ Self-Update │
│ (git pull) │
└───────────────────┘
│
▼
┌───────────────────┐
│ Pre-flight Check │
│ (skip draft/closed)
└───────────────────┘
│
▼
┌───────────────────┐
│ Gather Context │
│ • Fetch diff │
│ • Get CLAUDE.md │
│ • Load rules │
└───────────────────┘
│
▼
┌───────────────────────────────────────────────────┐
│ PARALLEL AGENT EXECUTION │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐│
│ │Security │ │ Bugs │ │ Tests │ │Guidelines││
│ │ (Opus) │ │ (Opus) │ │(Sonnet) │ │ (Sonnet) ││
│ └─────────┘ └─────────┘ └─────────┘ └──────────┘│
│ ┌─────────┐ ┌─────────────────────────┐ │
│ │ Docs │ │ Sqitch (optional) │ │
│ │(Sonnet) │ │ (Opus) │ │
│ └─────────┘ └─────────────────────────┘ │
└───────────────────────────────────────────────────┘
│
▼
┌───────────────────┐
│ Consolidate & │
│ Report Findings │
└───────────────────┘
## samorev Code Review Report
- **MR:** example-org/example-repo!123 - Add user authentication
- **Author:** @developer
- **AI-Assisted:** No
| Pipeline | Coverage |
|----------|----------|
| [](link) | [](link) |
---
### BLOCKING ISSUES (1)
**HIGH** `src/auth/login.ts:45` - SQL Injection
> User input directly concatenated into query
> **Fix:** Use parameterized query with $1 placeholder
---
### NON-BLOCKING (1)
Minor issues and suggestions (high-confidence LOW, INFO severity).
**INFO** `src/auth/login.ts:12` - Missing docstring
> **Suggestion:** Add JSDoc describing parameters and return value
---
### POTENTIAL ISSUES (1)
Issues with moderate confidence (4-7/10). Review manually - may be false positives.
**MEDIUM** `src/auth/utils.ts:28` - Possible race condition *(confidence: 6/10)*
> Multiple async calls without locking
> **Suggestion:** Consider adding mutex or using atomic operations
---
### Summary
| Area | Findings | Potential | Filtered |
|------|----------|-----------|----------|
| CI/Pipeline | 0 | 0 | 0 |
| Security | 1 | 0 | 1 |
| Bugs | 0 | 1 | 0 |
| Tests | 0 | 0 | 0 |
| Guidelines | 0 | 0 | 0 |
| Docs | 1 | 0 | 0 |
| Sqitch Migrations* | 0 | 0 | 0 |
| Metadata | 0 | 0 | 0 |
*Only when the optional Sqitch migration checker is enabled for the reviewed repository
Note:
- **Findings**: High-confidence issues (8-10/10) - blocking or non-blocking per severity
- **Potential**: Medium-confidence issues (4-7/10) - review manually
- **Filtered**: Low-confidence issues (0-3/10) - excluded as likely false positives
---
### SOC2 COMPLIANCE (0)
All SOC2 checks passed.
---
*samorev-assisted review (AI analysis by [Tanya301/samorev](https://github.com/Tanya301/samorev))*samorev includes a testing framework to validate agent quality and catch regressions.
# Run unit tests (no API calls)
pytest tests/ -m "not api" -v
# Run integration tests (requires ANTHROPIC_API_KEY)
pytest tests/ -m "api" -v --model opus
# Limit fixtures for faster testing
pytest tests/ -m "api" --max-fixtures=3
# Save golden outputs for baseline comparison
pytest tests/ -m "api" --save-goldentests/
├── conftest.py # Pytest configuration and fixtures
├── test_agents.py # Unit and integration tests
├── fixtures/ # Test cases per agent
│ ├── security/ # Security agent test cases
│ ├── bugs/ # Bug hunter test cases
│ └── ...
├── golden/ # Baseline outputs for regression testing
└── lib/
├── compare.py # Semantic matching for findings
├── metrics.py # Quality metrics calculation
└── runner.sh # Agent invocation script
Each fixture is a directory with:
diff.patch- The code diff to analyzeexpected.json- Expected findings with semantic matchersmetadata.json(optional) - Additional context
Example expected.json:
{
"must_find": [
{
"severity_min": "HIGH",
"file": "vulnerable.py",
"line_range": [10, 15],
"issue_contains": ["SQL", "injection"]
}
],
"must_not_find": [
{
"file": "safe.py",
"issue_contains": ["false positive"]
}
]
}Agents are held to minimum quality standards:
| Agent | Min Recall | Max FP Rate |
|---|---|---|
| Security | 98% | 5% |
| Bugs | 95% | 10% |
| Tests | 85% | 15% |
| Guidelines | 80% | 20% |
| Docs | 80% | 20% |
The CI pipeline runs Bun tests/build plus the remaining Python compatibility tests for the Claude Code slash command.
samorev/
├── .claude/
│ ├── commands/
│ │ └── review-mr.md # Main review command (slash command)
│ └── settings.json # Claude Code permissions config
├── .gitattributes # Linguist overrides for compatibility helpers
├── src/ # Bun/TypeScript CLI
├── agents/
│ ├── security-reviewer.md # OWASP, secrets, injection
│ ├── bug-hunter.md # Runtime bugs, logic errors
│ ├── test-analyzer.md # Coverage, test quality
│ ├── guidelines-checker.md # Project conventions
│ ├── docs-reviewer.md # Documentation review
│ └── sqitch-migration-checker.md # Optional Sqitch migrations
├── lib/ # Python slash-command compatibility helpers
├── tests/ # Testing framework
│ ├── conftest.py # Pytest configuration
│ ├── test_agents.py # Agent tests
│ ├── fixtures/ # Test fixtures per agent
│ └── lib/ # Test utilities
└── README.md
- Create agent file in
agents/ - Update
.claude/commands/review-mr.mdto include the agent in Step 4 - For repository-specific agents (like Sqitch Migration Checker):
- Add conditional logic to only run for specific projects
- Document the scope in the agent file and README
samorev should follow the shared Samo repository layout: visible review policy and project rules live under samo/, while machine config lives under .samo/. For example, teams can keep samo/review-policy.md and samo/rules/*.mdc under review, with .samo/config.yaml pointing at those files. Legacy rules/rules/*.mdc files remain compatible during migration.
Rules can cover:
- Git commit standards (Conventional Commits)
- SQL style guide
- Shell script best practices
- Documentation standards
- Core development principles
- Writing rules (title capitalization, terminology, professional communication)
- Platform neutrality
- Binary units standards
Apache License 2.0
- Source history: seeded from https://gitlab.com/postgres-ai/rev
- License: Apache License 2.0 in this repository.
- Public package target: CLI-first
samorev reviewwrapper plus Claude Code/review-mrcommand pack. - Before the first tagged release, confirm repository owner approval for this repackaging and re-audit docs for stale install URLs, provider assumptions, and project-specific defaults.
- Issue Tracker: https://github.com/Tanya301/samorev/issues
- Source history: seeded from https://gitlab.com/postgres-ai/rev
- Claude Code: https://claude.ai/claude-code
