CodeepCodeep

Code Review in CI

codeep review is a deterministic reviewer: pattern rules over your changed files, no model involved. It runs in about a second, costs nothing, and gives the same answer twice. That makes it the rare AI-tool feature you can put on a required check without flakiness or a bill.

Everything on this page is offline and needs no API key — with one exception, the optional fix step, which hands the findings to an agent and does need one.

In the terminal

With no arguments it reviews your unstaged changes, falling back to a src/ scan when the tree is clean. Pass files to scope it.

$ codeep review
⚠ src/render.ts:20 innerHTML can lead to XSS vulnerabilities
→ Use textContent or sanitize input before using innerHTML
 
Score 94 · 2 warnings, 1 suggestion across 1 file

Options

FlagWhat it does
--jsonPrint the result as JSON instead of the markdown report
--fail-on <level>Exit non-zero at or above error | warning | info | none (default: error)
--fixLet an agent fix what was found. Edits the working tree and stops there
--fix-min-severity <level>Lowest severity a fix may act on: error | warning (default: warning)
--rulesList the built-in rule ids and exit
--aiAsk your provider for a contextual second opinion (advisory; needs a key)
Exit code is the whole contract. 0 when nothing at or above --fail-on was found, 1 when something was. --fail-on none never fails, which is how you roll this out to a team without blocking anyone on day one.

The GitHub Action

codeep-action wraps the same subcommand. It resolves the pull request's changed files through the GitHub API — so shallow clones are not a problem — runs the review over those, and renders the result three ways: inline annotations on the changed lines, a single self-updating summary comment, and the check's pass/fail status.

Add .github/workflows/codeep-review.yml:

name: Codeep Review
on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write   # to post the summary comment

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: VladoIvankovic/codeep-action@v1
        with:
          fail-on: error
Pin to an exact release for supply-chain safety. @v1 is a floating tag that moves with every patch. @v1.0.10 is immutable. The convenience of one is the risk of the other; pick deliberately.

Pull requests from forks

GitHub forces the workflow token to read-only on fork pull requests, regardless of what your permissions: block says. The review still runs and you still get annotations and a pass/fail check — only the summary comment is skipped, with a warning in the log. No finding is ever lost.

Do not reach for pull_request_target to get the comment back. That trigger runs with a write token, and checking out and executing an untrusted contributor's code under it hands them your secrets. If you need comments on fork pull requests, use the two-workflow workflow_run pattern instead.

Letting it fix what it finds

Off by default. With fix: true the action hands the findings to an agent, lets it edit the code, and opens a second pull request against the branch under review.

permissions:
  contents: write        # to push the fix branch
  pull-requests: write   # to open the fix PR and post the comment

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: VladoIvankovic/codeep-action@v1
        with:
          fix: true
          fix-min-severity: warning
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
One repository setting is required, and it is off by default. Turn on Settings → Actions → General → Workflow permissions → “Allow GitHub Actions to create and approve pull requests”. Without it the review runs, the agent fixes the code and the branch is pushed — and only the final step is refused, leaving the work stranded on a branch with no pull request. A workflow's own permissions: block cannot grant this one.

The key goes in env, not with. Reviewing needs none; only the fix agent runs a model. Any provider Codeep supports works — set that provider's own variable (ZAI_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, and so on). With none set, the action says so and skips the fix rather than failing quietly.

What it will not do

NeverWhy
Pushes to the branch under reviewYour pull request is left as you left it; fixes arrive separately, to read or close
Merges anythingA fix is a proposal, not a decision
Acts on suggestionsOnly error and warning — acting on opinion produces churn and buries what matters
Runs on fork pull requestsThe read-only token there cannot push a branch
Gets a shell, git, or the networkIt has file editing and the test runner, enforced by the same boundary as any custom agent

That boundary is real rather than a line in a prompt, and the audit record shows it working — a refused tool call is written down alongside the ones that succeeded.

The fix step runs after the review is reported and never changes the check's outcome. A fix that fails, or runs out of its fix-timeout (600 seconds by default), is reported as a warning and leaves the review's result alone.

Rules

Twenty built-in rules across security, performance, bugs, types, style and documentation. List them with their ids:

$ codeep review --rules
eval-usage error Use of eval() is dangerous…
inner-html warning innerHTML can lead to XSS…
hardcoded-api-key error Hardcoded API key detected

Add your own, or switch built-ins off, in .codeep/review.yml (or .json). Checked into the repo, so the CLI and the Action enforce the same conventions:

rules:
  - id: no-direct-db
    pattern: 'db\.query\('
    category: best-practice
    severity: warning
    message: Go through the repository layer
    suggestion: Use repo.find() instead
    extensions: ['.ts']

disable:
  - todo-comment

include: ['src/**']
exclude: ['vendor/**', 'dist/**']
Loading is deliberately forgiving. A missing, malformed or partly-invalid config never throws — bad entries are skipped with a warning and the review proceeds with whatever is valid. A typo in one rule should not take your check down.

Rolling it out

Start at fail-on: none. The comment and annotations appear on every pull request, nothing blocks, and after a week or two you know which rules your codebase actually disagrees with. Disable those, then tighten to error. Turning the gate on first is how a review tool gets switched off.