Aevrin

CLI Reference

Every aevrin command, its flags, and its exit codes.

All commands print human-readable status to stderr and results to stdout, so aevrin scan ... > report.txt captures just the report. Every command supports --help.

scan

aevrin scan TARGET [OPTIONS]

Runs the full scan pipeline against TARGET and prints a report.

ArgumentDescription
TARGETA GitHub URL, a local directory path, or a live MCP server URL. Required.
OptionDefaultDescription
--jsonoffMachine-readable JSON output instead of the terminal report.
--upload / --no-upload--uploadSave the result to your dashboard. On by default when logged in. Pass --no-upload for a purely local, ephemeral scan (e.g. in CI, where you don't want scan history persisted).
--fail-on SEVERITYhighMinimum finding severity that causes a non-zero exit code. One of critical, high, medium, low, info.

What gets checked depends on the target type:

Full pipeline: cloning (repos only), static analysis, secrets, dependencies, then the tool description check. See Introduction.

Exit codes:

CodeMeaning
0Scan completed; no findings at or above --fail-on.
1Scan completed; at least one finding at or above --fail-on.
2Could not run at all: not logged in, quota exceeded, unreachable API, or an invalid target or flag.
3Scan ran but is incomplete: a required tool category failed to execute (Docker not running, a missing binary, no network). This fires regardless of --fail-on, because an incomplete scan is never treated as a pass. See Concepts → Incomplete scans.
Fail a CI job only on unresolved criticals, keep local scan history out of the dashboard
aevrin scan . --fail-on critical --no-upload

The CLI uses version-pinned, disposable Linux containers. Keep Docker Desktop running with at least 4 GB assigned, use Linux containers on Windows, and allow its temporary-directory bind mounts. Current errors include a redacted scanner stderr excerpt, so an image-pull, mount, network, timeout, or memory problem is distinguishable from a vulnerability finding.

login

aevrin login

Starts the browser device-code flow and stores an API key at ~/.aevrin/credentials. Running it again while already logged in prints a warning and exits 0. Run aevrin logout first to switch accounts.

logout

aevrin logout

Removes the stored CLI credentials. It does not affect the separate hook credentials. See hook logout.

version

aevrin version

Prints the installed version. Equivalent to the top-level aevrin --version flag.

hook setup

aevrin hook setup

Logs in a separate credential (~/.aevrin/hook_credentials) for the Claude Code hook, then prints a .claude/settings.json snippet pointing at the hook script bundled inside this exact aevrin install, so there is nothing else to download or clone. See Hook for the full setup walkthrough and why hook and CLI usage are tracked separately.

hook logout

aevrin hook logout

Removes the stored hook credentials.

hook allow

aevrin hook allow TARGET

Grants a 10-minute override so the hook lets the next install of TARGET through despite unresolved high or critical findings. This is the "install anyway" path. TARGET must match exactly what the hook printed in its block message. This doesn't fix or dismiss the findings, it just doesn't block on them once.

findings triage

aevrin findings triage FINDING_ID STATUS [--reason TEXT]

Updates a finding's triage status. This is the "false report" path. STATUS is one of open, fixed, or false_positive. False-positive reports require --reason; the reason and triage timestamp are retained with the dashboard finding and exported report. Marking a finding false_positive excludes it from future hook-blocking checks and open-risk summaries. FINDING_ID comes from a hook block message or a --json scan's findings[].id.

Dispute a finding the hook just blocked on
aevrin findings triage 3fa85f64-5717-4562-b3fc-2c963f66afa6 false_positive \
  --reason "Generated test fixture; cannot authenticate against any environment"

fix

aevrin fix FINDING_ID

Generates an automatic fix for one finding and opens a draft pull request. Available on Pro and Team, and counts against your monthly auto-fix allowance.

The flow is deliberately conservative:

  1. A language model drafts a patch using the finding and its surrounding file context.
  2. The same scanner that produced the finding re-runs against the patched code.
  3. If the finding is still present, generation retries once with that failure as added context.
  4. If it still doesn't clear, Aevrin says so plainly rather than opening a pull request.
  5. Only a confirmed fix becomes a draft PR. Never a merge, and never a bypass of branch protection. Your allowance is decremented only when a PR is actually opened.

FINDING_ID comes from a hook block message or a --json scan's findings[].id. Findings that cannot be auto-fixed, such as dependency advisories or anything spanning multiple files, are reported as ineligible instead of attempted. A scan's --json output marks each finding with autofix_eligible so you can tell in advance.

Connecting GitHub is required before the first fix; if it isn't connected yet, the command prints the authorization URL and exits rather than failing silently.

Fix a finding the hook just blocked on
aevrin fix 3fa85f64-5717-4562-b3fc-2c963f66afa6