AI-powered code review platform. Collects, stores and displays code review results from CI pipelines; reviews run on Claude, Codex, DeepSeek or any OpenAI-compatible LLM via pluggable runners.
- Multi-project support with configurable prompts per project
- 5 review types: architecture, code, security, tests, operability
- Severity levels: critical, high, medium, low with traffic light system (red/yellow/green)
- reviewctl CLI — single binary for the full review cycle: prompt fetch, runner (claude / opencode / codex CLIs, or a direct LLM-API runner), upload, GitLab MR comments, HTML report
- Runner profiles — per-project runner configuration (runner type, model, effort, provider, optional fallback token) managed in the admin panel; one global default, any project may pin its own.
reviewctlpulls the resolved profile from the server so CI stays thin (correct image + credentials only) - Multi-review (panel + fusion) — a project may attach several runner profiles as a panel plus a judge;
reviewctlruns each member in its own git worktree (parallel, fault-tolerant), then the judge fuses them into one review while keeping the member reviews linked with per-issue provenance. Opt-in per project - GitLab MR inline comments — critical and high issues posted directly in the diff with cleanup on re-runs
- Session caching —
--session/--continueflags to reuse Claude prompt cache (~90% token savings) - Auto-migrations — pgmigrator integrated as Go library, runs SQL patches on server startup
- GitLab CI integration via generated CI component and Docker image
- Slack notifications for completed reviews
- VT admin panel for managing projects, prompts, users, and Slack channels
- REST + JSON-RPC API with auto-generated TypeScript clients and OpenRPC schema
GitLab CI (merge request)
-> reviewctl review
-> fetch runner profile + prompt (/v1/reviewctl/rpc/ → ReviewConfig, Prompt)
-> run the resolved runner (claude / opencode / codex / direct)
-> parse review.json + R*.md files
-> upload to reviewer (/v1/reviewctl/upload/$PROJECT_KEY/)
-> post GitLab MR comments (summary + inline issues)
-> generate HTML report
-> reviewer server stores results in PostgreSQL
-> frontend displays reviews / Slack notification sent
- Go 1.26+
- PostgreSQL
- Node.js 20+ (for frontend build)
# 1. Initialize config files
make init
# 2. Edit configuration
# Set database credentials in Makefile.mk and cfg/local.toml
# 3. Create and seed database
make db
# 4. Install frontend dependencies and build
make frontend-install
make frontend-build
# 5. Run the server
make runDefault admin credentials: admin / 12345
The server starts at http://localhost:8075. The review UI is available at /reviews/, the admin panel at /vt/.
Run locally with Docker Compose — builds the image from source and initializes the database automatically:
docker compose up -dThis starts PostgreSQL (exposed on port 6432) and the reviewer app on http://localhost:8080. The database schema and seed data (docs/reviewsrv.sql, docs/init.sql) are applied on first run.
To rebuild the image after code changes:
docker compose up -d --buildTo stop and remove containers (add -v to also remove the database volume):
docker compose downConfiguration file: cfg/local.toml
[Server]
Host = "localhost"
Port = 8075
IsDevel = true
BaseURL = "http://localhost:8075"
[Database]
Addr = "localhost:5432"
User = "postgres"
Database = "reviewsrv"
Password = ""
PoolSize = 5
[Sentry]
DSN = ""
Environment = ""| Method | Path | Description |
|---|---|---|
| POST | /v1/reviewctl/rpc/ |
Internal reviewctl JSON-RPC: ReviewConfig (resolved runner profile / multi-review panel), Prompt and FusionPrompt |
| POST | /v1/reviewctl/upload/:projectKey/ |
Create a new review |
| POST | /v1/reviewctl/upload/:projectKey/:reviewId/:reviewType/ |
Upload a review file |
| POST | /v1/upload/:projectKey/[...] |
Deprecated upload aliases (kept for older CI images) |
| Path | Description |
|---|---|
/v1/rpc/ |
Review API (projects, reviews, issues, feedback) |
/v1/rpc/doc/ |
Review API documentation (SMDBox) |
/v1/vt/ |
Admin API (users, projects, prompts, Slack channels, task trackers) |
/v1/vt/doc/ |
Admin API documentation (SMDBox) |
TypeScript clients are auto-generated at /v1/rpc/api.ts and /v1/vt/api.ts.
Review types: architecture, code, security, tests, operability
Severity levels: critical, high, medium, low
Traffic light system:
- Red: 1+ critical OR 2+ high issues
- Yellow: 1+ high OR 3+ medium issues
- Green: all other cases
reviewctl is a Go CLI that replaces the old bash + Node.js CI scripts with a single binary.
reviewctl review # Full cycle: prompt -> Claude -> upload -> GitLab comments -> HTML
reviewctl upload # Upload local review.json + R*.md to server
reviewctl comment # Post MR comments for an existing review
reviewctl version # Print versionKey flags: --key, --url, --runner (claude | opencode | codex | direct), --model, --session (prompt cache reuse), --continue (resume last session), --allow-dangerous-permissions (opencode --dangerously-skip-permissions, default true for unattended CI). All flags have env variable equivalents for CI. See reviewctl --help for details.
Runners: the runner and its model/effort/provider come from the project's runner profile (configured in the admin panel and fetched at run time); CI does not pass them. The --runner/--model/--effort/--api-* flags still override the profile for local runs.
claude(default) — Claude Code CLI, full agentic exploration.opencode— opencode CLI (any provider configured in opencode, incl. OpenRouter),--model provider/model.codex—codex execCLI (OpenAI Codex),--model gpt-5.1-codex.direct— calls the LLM API itself (no CLI) with a narrow review tool set (read/grep/glob/git_diff/ast, plushttp_fetchscoped to the project's task tracker). Prompt caching + diff preload make it the cheapest and fastest path. Adds--api-provider(deepseek|openai-compat|anthropic),--api-base-url,--effort(low..max); the API key comes fromREVIEW_API_KEY(orANTHROPIC_API_KEY/DEEPSEEK_API_KEY/OPENAI_API_KEY). Theast_*navigation tools shell out to the optionalast-indexbinary — auto-detected onPATH(the generated CI image installs it), with the index rebuilt per run; when absent the tools are simply not offered.
Task tracker access: the tracker token never appears in the prompt. reviewctl fetches it with the review config and hands it to runners out-of-band: CLI runners get it as the REVIEW_TRACKER_TOKEN env var (prompts reference $REVIEW_TRACKER_TOKEN in curl instructions), the direct runner offers the model an http_fetch tool locked to the tracker origin that injects the Authorization header itself. A REVIEW_TRACKER_TOKEN CI variable overrides the server-stored token. Backward compatible in both directions: a legacy reviewctl (which doesn't export the env var) receives the old-style prompt with the token substituted in, and a new reviewctl against an older server falls back to the same legacy prompt.
Multi-review: when a project attaches a panel of runner profiles plus a judge, reviewctl review runs each member in its own detached git worktree (parallel, fault-tolerant — one survivor suffices), then the judge fuses them into a single review and links the member reviews with per-issue provenance. Configured per project in the admin panel; CI runs the same reviewctl review.
make build-reviewctl # Build reviewctl binaryThe server can apply SQL patches automatically on startup using pgmigrator (integrated as Go library):
reviewsrv -config config.toml -patches /patchesPatches are stored in docs/patches/*.sql with YYYY-MM-DD-description.sql naming. The Docker image includes patches at /patches/. Docker Compose runs with --patches by default.
The admin panel (/vt/) provides ready-to-use CI configuration:
- Open Projects and click the CI button in the page header — it shows the Dockerfile and GitLab CI YAML.
- Build the Docker image from the provided Dockerfile.
- Add CI/CD variables to your GitLab project:
PROJECT_KEY— project key from reviewerREVIEWSRV_URL— reviewer server URL- credentials for the project's runner profile — e.g.
ANTHROPIC_API_KEYfor theclauderunner,DEEPSEEK_API_KEY/OPENAI_API_KEY/REVIEW_API_KEYfor thedirectrunner (or set a fallback token on the profile) REVIEWER_GITLAB_TOKEN— GitLab token for MR comments (optional)
- Paste the generated YAML into your repository's
.gitlab-ci.yml.
The CI job runs reviewctl review on merge requests. It fetches the resolved runner profile + prompt from the server, runs the configured runner, uploads results, and posts inline comments to the MR. Runner type, model and effort are managed centrally as runner profiles in the admin panel — CI does not pass them.
For local runs, click the Run button on a specific project row to get a ready-to-use bash script.
When deploying behind a reverse proxy, URLs should be split by access level:
Public (available within the closed network):
| Path | Description |
|---|---|
/reviews/ |
Review results UI |
/vt/ |
Admin panel |
/v1/rpc/ |
Review JSON-RPC API |
/v1/vt/ |
Admin JSON-RPC API |
Internal (CI and ops only, must not be exposed externally):
| Path | Description |
|---|---|
/v1/reviewctl/ |
reviewctl internal API (config, prompt, upload) |
/v1/upload/ |
Deprecated upload aliases + debug bundle upload (older CI images) |
/v1/debug/ |
Debug bundle viewer — raw runner transcripts and artifacts |
/debug/ |
pprof and service metadata |
/status |
Healthcheck (DB ping) |
Example nginx configuration:
# Public URLs — accessible within the closed network
location = / { proxy_pass http://reviewer:8075; } # redirects to /reviews/
location /reviews/ { proxy_pass http://reviewer:8075; }
location /vt/ { proxy_pass http://reviewer:8075; }
location /v1/rpc/ { proxy_pass http://reviewer:8075; }
location /v1/vt/ { proxy_pass http://reviewer:8075; }
# Internal URLs — deny on the public proxy; CI runners and monitoring
# reach the service directly (REVIEWSRV_URL), bypassing this proxy
location /v1/reviewctl/ { deny all; }
location /v1/upload/ { deny all; }
location /v1/debug/ { deny all; }
location /debug/ { deny all; }
location /status { deny all; }make run # Run server in dev mode
make build # Build server binary
make build-reviewctl # Build reviewctl CLI
make frontend-dev # Run frontend dev server (Vite)
make frontend-build # Build frontend (main + admin)
make generate # Generate RPC/VT code
make lint # Run golangci-lint
make test # Run tests with coverage
make tools # Install dev tools
make mod # Tidy and vendor Go modulesBackend: Go, Echo, zenrpc, go-pg, Prometheus, Sentry
Frontend: Vue 3, TypeScript, Tailwind CSS, Vite, Headless UI
MIT