The doloop CLI

Read and check AI code, on your own machine.

One command reads a codebase you have never opened. Another gates a change against that codebase's own conventions, before it merges. A third writes those conventions into AGENTS.md, so your AI writes fitting code from the first token. It runs locally, your source never leaves your machine, and the same input gives the same answer on every run. Bring your own model.

pip install doloopio

Read code you didn't write

Point it at a repo and it introduces itself: the areas, the load-bearing files the rest of the code leans on, and, per file, where the code steps outside the codebase's own conventions. A re-run gives the same map.

doloop read                    # your current change: what to skip, what to look at, and why
doloop read path/to/file.py    # map one unfamiliar file: its units and call graph
doloop read <commit>           # the same read for a specific commit
doloop read --open             # write a self-contained page and open it, all local
doloop read --serve            # serve the same page from 127.0.0.1 for a large repo
doloop read --scrub            # drag a window over the repo's history; every changed file
                               # gets a merge verdict, and the security lane shows the
                               # injection sinks that history introduced

A real run, reading Flask:

$ doloop read
APP MAP of flask - read the whole app as pseudocode
84 files. Deterministic.

THE SPINE - files the rest of the repo leans on most. start here.
  imported by  29   src/flask/globals.py
  imported by  25   src/flask/helpers.py
  imported by  23   src/flask/typing.py
  imported by  20   src/flask/signals.py
  imported by  17   src/flask/wrappers.py

Gate what the AI wrote

On a commit, doloop looks at the changed functions and flags the ones that break a convention the rest of your code keeps, with the rule, the line, and the rate. Safety breaks block; local style warns. It speaks up only where the change is out of step with the codebase itself.

doloop gate --staged           # gate your staged change; a non-zero exit blocks the commit

A clean change:

$ doloop gate --staged
read 1353 files (the whole codebase). checking your staged change:
no findings - your change is consistent with the codebase and with itself.

And a block. This one caught a real bug in doloop's own engine before it could ship:

$ doloop gate --staged
  [block] read.py:_full_blob(): swallows an exception - this codebase does it right 87% of the time
1 to fix, 0 to consider. commit blocked.

Suppressing a finding is a human review decision, recorded with a reason, not something a tool or an agent can do to quiet the gate.

Teach your AI the house rules

The strongest move is to prevent the ill-fitting change, not catch it. doloop writes the conventions it infers from your codebase into the files your AI already reads, so it writes fitting code from the first token.

doloop conventions --emit agents   # write the house rules into AGENTS.md
doloop conventions --emit claude   # ... or CLAUDE.md
doloop conventions --emit cursor   # ... or a Cursor rule

What it wrote for one engine, inferred from the code itself, not a generic rulebook:

## House conventions (inferred by doloop from the whole codebase)
1. Bounds-check any parameter-derived index or length (house does it 94% over 18 sites).
2. Diagnostics use print (100%).
3. Act on caught errors, no silent except (held 72%).
4. Immutable default arguments (held 100%).

Remember your team's rulings

When a reviewer decides a flagged pattern is fine here, doloop records that ruling with a reason and an author, and applies it on every later run. A human ratifies; the machine remembers and applies, reproducibly. The map it builds of your codebase is yours.

doloop suppress <key>          # record a ruling: accepted here, with a reason
doloop ratchet                 # show the accumulated, auditable corrections

Command reference

read

doloop read

Read an unfamiliar repo, file, or commit. Add --open or --serve for a local page, --scrub for the commit-history view with merge verdicts and the security diff-gate.

gate

doloop gate --staged

Gate a staged change against the codebase's own conventions. Exit non-zero to block a commit or a CI step.

emit

doloop conventions --emit

Write the inferred house rules into AGENTS.md, CLAUDE.md, or a Cursor rule, so the AI writes fitting code up front.

ratchet

doloop ratchet / suppress

Record a reviewer's ruling with a reason, and apply it on every later run. The accumulated corrections are auditable.

age

doloop age

Date the conventions young versus settled, so the gate warns rather than blocks on a rule the codebase only recently adopted.

selftest

doloop selftest

Reproduce the engine's own determinism check on your machine. You do not take our word for it; you re-run it.

Local, deterministic, yours

Everything above runs on your machine. Your source is never uploaded and we never train on it. The same input gives the same verdict on every run, so a teammate or a regulator re-runs it and gets your exact result. Prefer a hosted endpoint for a single function? Send it to the API instead, nothing else leaves:

curl -s https://api.doloop.io/v1/check-code \
  -H "content-type: application/json" \
  -d '{"code": "<your function>"}'

Back to the code check →