merge-mind0
v0.1.9
Published
AI-powered pull request reviewer for Azure DevOps — self-hosted, webhook-driven, posts inline comments via OpenAI-compatible models
Maintainers
Readme
MergeMind: AI PR Reviewer for Azure DevOps
Automated AI code review for Azure DevOps pull requests. When a PR is assigned to a configured reviewer identity, this service fetches the changes, runs an AI review, and posts inline comments + a sticky summary back to the PR. Supports incremental rounds when developers push new commits.
What you get
- 🔁 Multi-round reviews — Round 2+ automatically classifies prior findings as
still-open,resolved, orregressed; sticky summary updates in place. - 🛑 Cost guardrails — daily review/token caps, per-PR rounds cap, per-review token budget with graceful degradation (
full → no_related → diff_only → refused). - 🔌 Multi-provider AI — OpenAI, Azure OpenAI (with Managed Identity), or Anthropic (Claude) — all behind a single
ResponsesClientinterface. Configurable via env. - 🧠 Multi-language context — TypeScript, JavaScript, Python, C#, Java dependency analysis pulls in related files (imports, callers) so the AI sees more than just the diff.
- 🚫 Won't-fix marking — mark individual findings as "won't fix" from the Web UI; the corresponding ADO thread is closed automatically. Won't-fix findings can be hidden from the round view with a toggle.
- 📬 Admin email alerts — SendGrid notifications for permanent failures (auth, quota, poison jobs) with per-(type, scope) throttling.
- 👀 Built-in web UI — read-only React UI at the same port: dashboard with live SSE updates, PR/round detail, retry-failed-posts, health.
- 🎯 Ad-hoc queue with token-estimate preview — queue any PR straight from the Web UI via a 3-step wizard: see estimated tokens, budget cap, and scope-mode (
full/no_related/diff_only) before it runs, optionally override the prompt addendum or exclude paths for that one run, then queue (with a "Queue Anyway" override if it exceeds budget). - 🪶 Single-process — one Bun process, one SQLite file. No Redis, no queue infrastructure. Reviews run serially to keep cost predictable.
Installation & Running
Using Docker (Recommended)
docker pull your-registry/merge-mind:latest
docker run -p 53847:53847 \
-v $(pwd)/data:/app/data \
--env-file .env \
your-registry/merge-mind:latestUsing Bun
If you have Bun installed:
bun install -g merge-mind
merge-mindUsing Kubernetes
Manifests + runbook (ConfigMap, PVC, Deployment, Service, Ingress) are in cicd/k8s/ of this repo. Key constraint: this service is a single Bun process backed by SQLite, so the Deployment must stay at replicas: 1 with strategy: Recreate (no HPA), on block storage (not NFS/Azure Files), with the ingress configured for long read timeouts and buffering disabled for SSE and the streaming estimate endpoint.
Connect Azure DevOps
In your ADO project → Project Settings → Service Hooks → New Subscription:
- Service: Web Hooks
- Trigger: Pull request created (also create a second subscription for Pull request updated — both call the same webhook URL)
- Filters: leave default (the service does its own filtering by reviewer)
- Action → URL:
https://your-host/webhook/azuredevops(must be HTTPS reachable from ADO) - Action → Basic authentication:
- Username: matches
WEBHOOK_USER - Password: matches
WEBHOOK_PASSWORD
- Username: matches
- Save → Test to verify a 200 comes back.
For the trigger to fire, also assign the configured reviewer identity (the email/group in REVIEWER_TRIGGER_LIST) to the PR. The reviewer can be a real user account or a designated bot account.
Configuration reference
Environment variables
| Var | Required | Default | Description |
|---|---|---|---|
| WEBHOOK_USER | no | ai-reviewer | Basic Auth username for the ADO webhook |
| WEBHOOK_PASSWORD | yes | — | Basic Auth password for the ADO webhook |
| WEB_UI_USER | optional | — | Basic Auth username for the Web UI/dashboard. If unset (with WEB_UI_PASSWORD), the Web UI has no auth |
| WEB_UI_PASSWORD | optional | — | Basic Auth password for the Web UI/dashboard; pairs with WEB_UI_USER |
| AZURE_DEVOPS_ORG_URL | yes | — | e.g. https://dev.azure.com/yourorg |
| ADO_AUTH_MODE | optional | auto | pat | managed-identity | auto — how the service authenticates to the ADO REST API |
| AZURE_DEVOPS_PAT | if ADO_AUTH_MODE=pat | — | PAT for ADO API access. Not needed under auto/managed-identity when running on Azure infra with a system-assigned identity |
| REVIEWER_TRIGGER_LIST | yes | — | Comma-separated reviewer identities; PR triggers when any match |
| AI_PROVIDER | yes | — | openai | azure-openai | anthropic |
| OPENAI_API_KEY | if openai | — | |
| OPENAI_BASE_URL | optional | — | For self-hosted OpenAI-compatible endpoints (vLLM, Ollama, etc.) |
| AZURE_OPENAI_ENDPOINT | if azure-openai | — | e.g. https://yourname.openai.azure.com |
| AZURE_OPENAI_API_KEY | optional | — | If unset, falls back to DefaultAzureCredential (Managed Identity) |
| AZURE_OPENAI_API_VERSION | optional | — | API version for Azure OpenAI calls |
| ANTHROPIC_API_KEY | if anthropic | — | |
| AI_MODEL | yes | — | Model id, e.g. gpt-5, claude-sonnet-4-6 |
| SENDGRID_API_KEY | optional | — | Enables admin email alerts |
| NOTIFY_ADMIN_RECIPIENTS | optional | — | Comma-separated email addresses for alerts |
| NOTIFY_FROM_ADDRESS | optional | — | "From" address for SendGrid admin alert emails |
| NOTIFY_SEVERITY_FLOOR | optional | warning | Minimum severity (info|warning|critical) that triggers an admin email |
| NOTIFY_THROTTLE_MIN | optional | 60 | Minutes between repeated alerts of the same (type, scope) |
| DB_PATH | optional | data/ai-reviewer.db | SQLite file path |
| PORT | optional | 53847 | HTTP port |
| LOG_LEVEL | optional | info | trace | debug | info | warn | error | fatal |
| MAX_QUEUE_ATTEMPTS | optional | 3 | Max retry attempts for a queued review job before it's marked failed |
| SHUTDOWN_GRACE_MS | optional | 30000 | Graceful-shutdown grace period (ms) for in-flight jobs on SIGTERM/SIGINT |
Per-repo .ai-reviewer.yml
Drop a file at the root of any repo you want reviewed to override defaults for that repo.
enabled: true # set false to disable AI review for this repo
exclude_paths:
- "dist/**"
- "build/**"
custom_prompt_addendum: |
This repo uses TypeScript strict mode. Flag any `any` usage in new code.
severity_thresholds:
post_inline: ["must-fix", "should-fix"]
post_summary: ["must-fix", "should-fix", "nit"]
limits:
max_changed_files: 50
max_tokens_per_round: 200000Web UI
Visit http://localhost:53847 to access the dashboard.
| Route | What it shows |
|---|---|
| / Dashboard | Live queue status and recent activity. |
| /prs | Searchable list of all reviewed PRs; queue a new PR ad hoc via the estimate wizard. |
| /rounds/:id | Full report markdown, every finding grouped by severity. |
| /failed-posts | Findings whose ADO comment posting failed. |
| /health | Connectivity and usage status. |
| /settings | Runtime configuration (models, reasoning, estimate request timeout, etc). |
Operations
Health check
curl -u $WEB_UI_USER:$WEB_UI_PASSWORD http://localhost:53847/api/healthLogs
The service logs structured JSON.
Backup
The DB is a single SQLite file at data/ai-reviewer.db.
License
MIT
