Skip to content
avifeneshPublic

About

Local, supplier-agnostic, repo-agnostic autonomous PR reviewer that learns from maintainer feedback into graduated skills (any OpenAI-compatible model; Obsidian vault; SurrealDB/SQLite).

Resources

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

revuto

A PR reviewer that runs on your machine and learns how your team reviews.

CI CodeQL npm MIT license

Point revuto at a GitHub repo. It reads the repo's PR history, writes down what your maintainers care about, and reviews every new PR with that knowledge. When maintainers reply to its comments, it learns. Feedback that keeps coming back becomes a reusable skill.

Why revuto

  • Learns your repo. It builds a textbook from up to 1,000 past PRs and keeps adding to it from every review thread.
  • Runs on the plan you already have. Claude, ChatGPT, Gemini, GLM, Grok, a local model or Amazon Bedrock. Mix them per PR size.
  • Lives on your machine. One daemon, a local store, and an optional GitHub App for review-on-push.
  • Knowledge you can read. Skills are markdown notes in an Obsidian vault, or any folder. Nothing is written into the reviewed repo.
  • Real tools, behind a sandbox. Claude Code and Codex reviewers get a shell, file tools, git history, Python and a scratch directory, under auto mode or Codex's sandbox: no network, no credentials, no home directory reads, nothing from the checkout loaded as configuration, and no repository code run. Revuto posts the review itself, after stripping mentions, HTML and secrets.

Quick start

git clone https://github.com/avifenesh/revuto && cd revuto   # Node 22 or newer
npm install && npm run build && npm link
revuto init-config         # writes ~/revuto/revuto.config.json

The npm release (revuto 0.1.1) predates the Claude Code, Codex, Antigravity and Grok reviewers and the GitHub App. Install from source until the next release.

Pick a reviewer from the next section and put it in models.review. Then:

export GH_TOKEN=ghp_...    # or: gh auth login; not needed with the GitHub App
revuto doctor              # checks models, store and GitHub access
revuto init owner/repo     # clone, read PR history, write the textbook
revuto daemon              # review, learn and decay on schedule

The default memory store is SurrealDB: start it with scripts/surreal-start.sh. For no extra dependencies, set "store": { "backend": "sqlite" }; better-sqlite3 ships prebuilt binaries.

Bring your own plan

you have revuto runs sign in with
Claude Pro or Max Claude Code claude setup-token, then CLAUDE_CODE_OAUTH_TOKEN
a ChatGPT plan Codex mkdir -p ~/.config/revuto/codex && CODEX_HOME=~/.config/revuto/codex codex login
an Anthropic API key Claude Code ANTHROPIC_API_KEY
an OpenAI API key Codex OPENAI_API_KEY
a Google account Gemini through Antigravity the agy login
the Z.ai coding plan GLM ZAI_API_KEY
Grok Grok the Grok CLI login or GROK_API_KEY
a GPU llama.cpp, vLLM, Ollama or any OpenAI-compatible server nothing
AWS, Google Cloud or Azure Claude on Bedrock, Vertex or Foundry; GPT on Bedrock your cloud credentials

A reviewer on your Claude plan:

{ "api": "claude", "baseURL": "claude-cli://local", "auth": "subscription", "model": "claude-opus-5-5", "reasoningEffort": "high" }

On your ChatGPT plan:

{ "api": "codex", "baseURL": "codex://openai", "auth": "subscription", "model": "gpt-6.1-sol", "reasoningEffort": "high" }

Mix them. Big PRs go to Claude (Codex takes over if Claude refuses), small ones to Codex, Gemini curates skills and GLM distills PR history:

"models": {
  "review":      { "api": "claude", "baseURL": "claude-cli://local", "auth": "subscription", "model": "claude-opus-5-5", "reasoningEffort": "high",
                   "fallbacks": [{ "api": "codex", "baseURL": "codex://openai", "auth": "subscription", "model": "gpt-6.1-sol", "reasoningEffort": "high" }] },
  "reviewSmall": { "api": "codex", "baseURL": "codex://openai", "auth": "subscription", "model": "gpt-6.1-sol", "reasoningEffort": "medium" },
  "curator":     { "api": "agy", "baseURL": "agy://local", "auth": "agy-oauth", "model": "gemini-4-argon-high",
                   "fallbacks": [{ "baseURL": "https://api.z.ai/api/coding/paas/v4", "model": "glm-5.3", "apiKeyEnv": "ZAI_API_KEY" }] },
  "distill":     { "baseURL": "https://api.z.ai/api/coding/paas/v4", "model": "glm-5.3", "apiKeyEnv": "ZAI_API_KEY" },
  "embedder":    null
}

Claude Code and Codex run the review tiers. The curator and distiller run on any HTTP model or Antigravity. The embedder is optional; without one, dedup and skill selection fall back to an LLM judge and area globs.

Every provider, its isolation and its knobs: docs/providers.md.

How it works

flowchart LR
  init["init<br/>read up to 1,000 PRs"] --> textbook["textbook<br/>in your vault"]
  textbook --> review["review<br/>every new PR head"]
  review --> replies["maintainers<br/>reply"]
  replies --> learn["learn<br/>dedup into concerns"]
  learn -- "reinforced 4 times" --> skill["topic skill"]
  skill --> review
Loading
  • init clones the repo, scans its structure, backfills up to 1,000 PRs, distills what maintainers care about and writes <vault>/skills/<repo>/_textbook.md. Only feedback from people with write access counts, never the PR author's own comments or bots.
  • review claims the exact PR head, checks it out, picks the textbook and the relevant skills, runs the reviewer, then posts a review or skips. A webhook triggers it; a cron pass catches anything missed.
  • learn reads replies to revuto's comments, filters noise and dedups them into concerns. A concern reinforced four times graduates into a topic skill, and the concern is deleted.
  • guard checks every comment before it is learned from, every concern before it is stored or rewritten, and every skill and textbook before it is saved. It is a model with no tools that reads the candidate as untrusted data, rejects anything that tries to steer reviews, and fails closed.
  • decay ages out concerns that never graduate.

New skills land as draft and load only after revuto approve. Repos with autoActivate graduate them as active right away, once the guard approves them. Revising a skill keeps the old version under _history/, and a draft revision of an active skill is written beside it as <slug>-revision instead of replacing it. Skill and reviewer notes must use YAML front matter; a note in any other front matter language is skipped, never evaluated.

Review on push

Polling works with no public endpoint. For reviews within seconds of a push, install one GitHub App on the accounts you want covered and point its webhook at the daemon. Each PR head gets a revuto-review check: a clean review passes it and approves that exact head, and findings fail it. Setup, a Tailscale Funnel recipe, and the self-healing webhook monitor: docs/github-app.md.

Reviews that fit the PR

  • Three tiers. Docs-only and small PRs go to models.reviewSmall, mid-size ones to models.reviewMedium, the rest to models.review. Risky paths and learned hotspots always get the large tier. Routing costs no model call.
  • Re-reviews look at what changed since revuto's last reviewed head.
  • A round cap (3 by default) stops endless review and fix loops. After the cap, revuto review owner/repo 123 --final runs one last review of the head that will merge.

Tiers, escalation, shadow sampling and exit codes: docs/reviews.md.

Commands

revuto doctor                        # verify endpoints + GitHub token first
revuto init <owner/repo> [maxPRs]    # onboard a repo (clone + backfill + textbook)
revuto daemon                        # start scheduler + configured GitHub App webhook

# lifecycle
revuto add <owner/repo>              # register without onboarding
revuto remove <owner/repo> [--purge] # unregister (--purge also deletes its skills and memory)
revuto pause <owner/repo>            # stop scheduling (until resume; survives restarts)
revuto resume <owner/repo>           # re-enable scheduling
revuto cron <owner/repo> <job> <expr>  # per-repo cron for review|learn|decay ("clear" resets to default)
revuto list                          # list registered reviewers (shows PAUSED)

# run a job now
revuto trigger <owner/repo> [job]    # run review|learn|decay now (default: review)
revuto review <owner/repo> <pr>      # review one specific PR now (exit 0 passed, 2 concerns, 3 not run, 1 failed)
revuto review <owner/repo> <pr> --final  # one review of the current head after review.maxRounds
revuto learn <owner/repo>            # run one learn pass now
revuto decay <owner/repo>            # run decay now
revuto approve <owner/repo> <slug>   # activate a draft skill

Configuration

Config, skills and reviewer notes live together in the vault (~/revuto, or $REVUTO_VAULT), so you can read and edit all of it in Obsidian. No secrets are stored there: API keys and the webhook secret are referenced by environment variable name. Optional daily caps on reviews, learn passes and tokens bound the spend.

Config keys, storage backends, limits and systemd units: docs/configuration.md.

Development

git clone https://github.com/avifenesh/revuto && cd revuto
npm install && npm run build
npm run typecheck
npm test
npx tsx scripts/smoke/graduation.ts    # store + 4× graduation + selection
npx tsx scripts/smoke/loop.ts          # full learn loop (fake endpoint)
npx tsx scripts/smoke/responses.ts     # /v1/responses + Bedrock Mantle auth
npx tsx scripts/smoke/doctor.ts        # doctor probes + output shape
npx tsx scripts/smoke/config.ts        # config defaults + model API validation
npx tsx scripts/smoke/webhook.ts       # GitHub webhook HMAC + dispatch/check outcomes
npx tsx scripts/smoke/scheduler.ts     # registry + schedule planning
npx tsx scripts/smoke/scan.ts          # onboarding repo scan
npx tsx scripts/smoke/codex-tools.ts   # tools a real Codex CLI offers a review (after npm run build)
npx tsx scripts/smoke/native-sandbox.ts claude|codex  # a real review of a hostile checkout (needs model creds)

License

MIT

About

Local, supplier-agnostic, repo-agnostic autonomous PR reviewer that learns from maintainer feedback into graduated skills (any OpenAI-compatible model; Obsidian vault; SurrealDB/SQLite).

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages