SuperAPI AI Directory

crew-code-review

Deployment & operations

View repository

Updated 10-16 09:58

About this skill

PR review queue with crew-code-review

crew-code-review is a CLI binary on $PATH. Default output is NDJSON: one JSON record per line on stdout (-f json|yaml wrap a list as one {"data": [...]} document; run and score recompute|refetch end with an {"@summary": {...}} line). Errors go to stderr as one JSON line {"error": "...", "fixable_by": "agent"|"human"|"retry", "hint": "..."} with a non-zero exit.

It maintains a DuckDB-backed queue of candidate PRs and reviews them with a pluggable engine (Codex or Claude Code; default: Codex). Configuration lives at ~/.config/app.paulie.crew-code-review/config.json: repos, the author groups, age thresholds, schedule, and the review prompt + rules.

Inspect the queue

crew-code-review queue ls                   # all pending candidates, NDJSON
crew-code-review queue ls --repo owner/name

The queue holds only pending work, FIFO by first discovery; a row with claimed_at set is being reviewed right now, and a row carries a holds map of name to expiry (settling = the PR was pushed or edited within candidates.quiet_period; cooldown = we reviewed it within candidates.rereview_cooldown; editing = its author has the dashboard's steering editor open, for candidates.steering_hold). It is dispatched once every one of them is past, keeping its queue position and being stepped over until then. Completed outcomes live in history (see the dashboard's History page).

Manage candidates

crew-code-review queue add     owner/name 1234   # add a PR (fetches live metadata; rejects closed/merged; no holds)
crew-code-review queue promote owner/name 1234   # review NOW: top of queue, clears any hold, treated as manual
crew-code-review queue skip    owner/name 1234   # record SKIPPED and drop (re-eligible on new commits)
crew-code-review queue rm      owner/name 1234   # remove, recording nothing
crew-code-review queue prune --dry-run            # recheck the whole queue now: skip stale discovered PRs, warn about merged/closed manual adds
crew-code-review queue log     owner/name 1234 -f # stream the review agent's log (live or postmortem)

Manage the author roster (which group each author is in, per repo, in DuckDB)

crew-code-review authors set owner/name alice core --name "Alice" --slack-id U01
crew-code-review authors set '*' bob outsider     # that group on every repo
crew-code-review authors ls --repo owner/name     # rows + the policy each resolves to
crew-code-review authors groups                   # the cohorts and what each grants
crew-code-review authors who alice --repo owner/name
crew-code-review authors rm owner/name alice

We are the reviewer. An author belongs to ONE group per repo, and the group (defined in config under authors.groups) is a complete review policy: the review level (ignore = never discovered, though a manual queue add still reviews; comment = reviewed but never approved; approve = approvable), plus the engine, model, effort, and an extra prompt fragment. authors.overrides narrows any of that per handle.

Resolution: the roster row for this repo, else the row for *, else authors.unlisted[repo], else authors.unlisted["*"]; then every matching override patches it field by field. authors who names the deciding layer per field, which is how to answer "why did that PR get approved / ignored". Only this PR's own resolved policy reaches the engine, never the roster.

Author scores and the leaderboard

Every completed review earns the PR's author points, from the diff's size, the verdict, whether the codebase grew or shrank, and how many revisions it took. Generated and vendored files are excluded, read from the repo's own .gitattributes.

crew-code-review score leaderboard                  # standings, highest first
crew-code-review score leaderboard --days 30        # a window
crew-code-review score show owner/repo 123          # every scored review of one PR
crew-code-review score ls --missing                 # rows that were never scored

A score has two parts. SIZE is a curve over added-plus-removed lines, peaking in points per line at piece_lines (50 changed lines), and paying at most size_points (100) for one PR before verdict and decay, so the same solve in fewer lines is worth more and a stack of well-sized PRs beats one enormous one; it is quadratic near zero, so atomising work into one-line PRs earns nothing at the defaults. REMOVAL is removal_points_per_100 (20) for every hundred NET removed lines, paid on top. Deleting more never earns less at the defaults; tuned size rewards can decline faster than the removal component grows. Linear removal is split-neutral before rounding only across net-deleting pieces with the same verdict and revision multiplier.

+100/-100 scores 100, +1000/-1000 scores 29, +100/-1000 scores 227, +1000/-100 scores 47, and -2000 scores 429.

Scores are frozen when a review completes, alongside a hash of the rules that produced them, so retuning config changes what FUTURE reviews earn and nobody loses points they already have.

crew-code-review score ls --stale                   # scored under older rules
crew-code-review score recompute --stale --dry-run  # what would change
crew-code-review score recompute --stale            # apply it
crew-code-review score refetch --missing            # re-measure from GitHub
crew-code-review score set owner/repo 123 0 --note "duplicate of #120"

recompute is offline: it re-derives from each row's stored measurement, so changing which paths are excluded needs no network. refetch asks GitHub again and is the only repair for a row whose size was never measured; it needs the PR to still be at the head that was reviewed.

Both move points people already have, so both refuse to touch all of history without --all, both take --dry-run, and a score set by hand is left alone unless --include-manual is passed.

Run reviews

crew-code-review run                                # drain the queue, then exit
crew-code-review serve --http :8330                 # daemon + dashboard
crew-code-review serve --http :8330 --tailscale serve   # + expose on tailnet

Configuration

crew-code-review config path      # where the config lives
crew-code-review config show      # current config (NDJSON)

See config.example.json in the repo for the full shape. The CLI never hardcodes repos or GitHub handles; everything is config.

Notes

  • Requires gh (authenticated), the duckdb CLI, and the configured review engine (codex by default, or claude) on $PATH, already authenticated.
  • Candidate rules: NEW (never reviewed, ≤14d) and REFRESHED (head SHA changed since our last review, ≤21d). Processed FIFO by first discovery, up to 4 in parallel. Already-approved PRs are skipped, and any recorded outcome at the current head SHA suppresses re-enqueueing.
  • Discovered candidates wait out eligibility holds (quiet period default 15m, re-review cooldown default 90m, 0s disables) so the agent doesn't review mid-push or instantly re-review; queue promote or a manual queue add bypasses them. Manual rows also skip the pre-review candidacy recheck.
  • Most config edits reload live within ~30s (cadence, parallelism, usage floors, repos, prompts); only the loop switches and dashboard/Tailscale settings need a daemon restart. A candidate is HELD when the engine that would review it drops below <engine>.usage_floor.{5h,1w}_percent remaining. Both the meter and the floor are per engine, so one engine being out of headroom does not hold candidates bound for the other; a cohort can set its own under authors.groups.<name>.usage_floor.<engine>. A held candidate is never claimed or recorded, so it runs when the window refills.
  • The agent does the actual review and GitHub actions, then reports back what it did (APPROVED|COMMENTED|REQUESTED_CHANGES|SKIPPED). The assembled prompt carries a built-in approval directive that defaults to comment-only; approval needs an approve-level group AND a non-self-authored PR (the self-review veto sits above the group cascade and no group can lift it). Post-outcome behaviour comes from review.on_approve/on_comment/on_reject in config.
  • Manage watched repos with repos ls|add|rm, prompts with prompts show|set|unset|preview, and scalar dials with config list|get|set|unset (all persisted to config.json).
  • Scoring can be switched off globally with config set scoring.mode: enabled (measure and score), leaderboard-only (stop measuring, which removes the per-review GitHub call scoring adds, while still showing the points already earned), or disabled (also hides the leaderboard in the dashboard). It can be narrowed per repo under scoring.repos.
  • A second review at the same commit (somebody replying to the bot) scores 0: it is discussion, not new work. The leaderboard pays once per revision.
  • Every command group has a usage subcommand with full docs and examples.