npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

argus-review

v0.2.5

Published

Self-hosted AI code review for GitHub, GitLab, Bitbucket and Azure DevOps: CLI, CI, web UI and webhooks

Downloads

989

Readme

Argus

Self-hosted AI code review for GitHub, GitLab, Bitbucket (Cloud and Server) and Azure DevOps. Argus reviews pull requests the way a careful staff engineer would. It reads the full changed files and the code around them, and it verifies every finding before posting. Comments are inline, with one-click fixes, and the summary is kept up to date. It learns from your team's feedback.

It runs four ways, from the same engine and settings:

| Mode | Command | Use it for | |---|---|---| | Server + web UI | argus serve | Webhook-driven reviews, settings UI, review history, chat and learnings | | One pull request | argus review <url> | Reviewing any PR or MR from your terminal | | CI | argus ci | GitHub Actions, GitLab CI, Bitbucket Pipelines or Azure Pipelines, with no server | | Local | argus local / argus hook install | Reviewing staged changes before you commit |

How a review works

  1. Scope. Lock files, generated, minified, vendored and binary files are skipped, plus your own path filters. Re-reviews only look at commits pushed since the last review.
  2. Intent. The title, description, commits and an AI summary tell the reviewer what the change is supposed to do.
  3. Context. Linked issues (#12, owner/repo#7, issue URLs, Jira or Linear keys such as PAY-42) are read and their acceptance criteria checked against the diff. Each changed file is shown in full with line numbers and +/- markers. Argus also adds files it imports and other places that use the changed symbols (via git grep on a local mirror). Repository guidelines (AGENTS.md, CLAUDE.md, .cursorrules, .cursor/rules, copilot-instructions.md, nested per directory, read from the target branch), your team guidelines, custom rules, path instructions and learnings all go into the prompt. Everything taken from the pull request is marked as data, not instructions.
  4. Static analysis. The repository's own tsc and ESLint (they execute repository code, so only inside the test sandbox or on your own checkout with argus local), plus Ruff, Semgrep, Gitleaks, OSV-Scanner, ShellCheck, Hadolint and go vet (also sandbox-only, with cgo and network module downloads off) when installed, run on the changed files. Results on changed lines (and type errors elsewhere that mention a changed symbol) become evidence for the model. Leaked secrets and vulnerable dependencies are posted directly.
  5. Review with exploration. Files are reviewed in parallel batches against an explicit checklist: logic, security, performance, concurrency, error handling, data integrity, API contracts and more. The model can read files, search the code, find definitions and references and read history before it reports anything. Claude Code and Codex do the same in a read-only checkout.
  6. Multi-pass voting. High-risk files (auth, payments, migrations, money arithmetic, large changes, files named in the summary's risks) get extra passes with different lenses: adversarial, edge cases, contracts. Findings are clustered across passes. Agreement raises confidence, and lone findings need a stronger verification score.
  7. Cross-file pass. Catches contract changes whose callers were not updated.
  8. Secret scan. Deterministic detection of keys and tokens in added lines.
  9. Verification. A second model pass, also able to explore the repository, re-derives every finding from the code and discards speculation, already-handled cases and style noise. Each finding gets a 0-10 score. A skeptical second verifier must also confirm every critical finding. Verification fails closed: a finding without a usable verdict (verifier error, missing or unknown verdict) is suppressed, with the reason recorded.
  10. Proof (opt-in, execution.enabled: true). It runs pull request code, so it is off by default. In a Docker sandbox, Argus installs the dependencies (with network) and runs the test suite (without network). It detects vitest, jest, node --test, npm test, pytest and go test. A failing test that passes on the base branch is reported as a regression. For serious findings the model writes a test that should fail because of the bug. It is marked as reproduced only if the test fails and then passes once the suggested fix is applied (or there is no suggested fix).
  11. Follow-up. On every push, findings whose code changed are re-checked; fixed ones get a "✅ Fixed in abc123" reply and their thread is resolved. Fixes, 👍/👎 reactions and replies such as "false positive" are tracked per category, and categories a team keeps dismissing need more confidence.
  12. Anchoring and dedupe. Quoted code is relocated to the right lines and mapped onto the diff. Near-duplicates are merged, and findings posted in earlier reviews are not repeated.
  13. Publish. Inline comments go out with severity, category, the analyzers that confirm them, how many passes found them, a committable suggestion and a "prompt for AI agents". One persistent summary comment holds the walkthrough, a changes table, a sequence diagram, the review effort and findings outside the diff. The PR is optionally approved or marked as changes requested; approval is only given when the review ran to completion (no errors, no unverifiable findings, no files skipped for the size limits, at least one file reviewed).
  14. Merge gate. An argus commit status goes to pending when the review starts and ends as failure (a finding of at least review.status.failOn, default major), error (the review did not complete, timed out or crashed) or success. Make it a required check to block merges until Argus passes; see Blocking merges.

Every dropped candidate is kept with its reason, and the web UI shows it under Filtered out.

Requirements

  • Node.js 22.12 or newer, and git
  • A model: an OpenRouter, Anthropic or OpenAI key, any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio, a company gateway), or a Claude Pro/Max, ChatGPT or GitHub Copilot plan through the official claude, codex or copilot CLI

Install

Pick one:

npm install -g argus-review                                   # the `argus` CLI with the web UI, Node 22.12+
docker compose -f deploy/docker-compose.yml up -d             # server in Docker (copy deploy/.env.example to deploy/.env first)

The Docker image ghcr.io/anevski-stefan/argus is private. To pull it, the image owner adds you under the package's Manage access on GitHub, and you sign in once with a GitHub token that has the read:packages scope:

echo "$GITHUB_TOKEN" | docker login ghcr.io -u <your-github-user> --password-stdin

Without access, build the image from a checkout instead: docker compose -f deploy/docker-compose.yml up -d --build.

On a plain Ubuntu or Debian VM (x86 or ARM, for example Oracle Cloud Always Free), deploy/install-server.sh installs Node 22, argus-review, a systemd service and Caddy with HTTPS on <public-ip>.sslip.io: sudo [email protected] bash install-server.sh.

To run unreleased changes from main on such a server without publishing a version, run deploy/deploy-main.sh ubuntu@your-server (set ARGUS_SSH_KEY for a key file). It builds the package locally, installs it over SSH and restarts the service; the dashboard shows a dev version such as 0.2.5-dev.e6d00e0. Small changes collect under "Unreleased" in the changelog and ship with the next release.

From source:

git clone https://github.com/anevski-stefan/argus.git && cd argus
npm install && npm run build
npm link -w @argus/server      # puts `argus` on your PATH

For development without building, use bin/argus (it runs the TypeScript sources directly). Releases are listed in CHANGELOG.md.

Server and web UI

argus serve                    # http://127.0.0.1:4747, data in ~/.argus
argus serve --port 8080 --host 0.0.0.0

On the first visit, create the admin with the setup token printed at start-up (see Access and exposure). Then, in the UI:

  1. Models & providers. Add an API key, or log in to claude / codex / copilot in a terminal to use your plan. Pick a model for each stage (review, verification, summary, chat) and press Test connection.
  2. Repositories. Connect GitHub, GitLab, Bitbucket or Azure DevOps with a token (the dialog lists the exact permissions), then add repositories.
  3. Server & CI. Set the public URL (your domain or a tunnel) and press Install webhook on each repository. This works on all five platforms; an Azure DevOps token needs the Service Hooks (read, write & manage) scope for it, and a Bitbucket Server token repository admin.

Tokens and API keys are encrypted at rest (AES-256-GCM, key in ~/.argus/secret.key or ARGUS_SECRET_KEY). Stored provider keys are only sent to the model endpoints an admin configured (each vendor's default endpoint, plus the provider/base URL pairs in the global settings). Environment keys such as OPENAI_API_KEY are only sent to the vendor's own endpoint.

Access and exposure

  • No users yet: the API is locked (401 {setupRequired: true}) until the first admin is created, whatever address Argus listens on. The server prints a one-time setup token at start-up and the web UI asks for it on the first visit. Alternatively set ARGUS_ADMIN_EMAIL and ARGUS_ADMIN_PASSWORD, and that admin is created at start-up.
  • Without sign-in, on purpose: ARGUS_ALLOW_OPEN=1 serves every request as admin while there are no users, for example behind an authenticating proxy or for local development. Creating the first user turns it off.
  • Host and Origin checks: requests must use a loopback host, the public URL's host or a name in ARGUS_ALLOWED_HOSTS (comma-separated, *.example.com allowed, * turns the check off). State-changing API calls must not come from another origin and must send their body as application/json. Webhooks are exempt and authenticated by their own signatures.
  • Behind a reverse proxy: set ARGUS_TRUST_PROXY=1 so X-Forwarded-For/-Proto/-Host are honoured (client IPs for login throttling, Secure cookies). Only set it when Argus is reachable exclusively through that proxy.
  • Sessions: signing out ends every session of that user, and a password or role change ends that user's other sessions. Failed sign-ins are throttled per email and per IP.

Boolean variables accept 1/true/yes and 0/false/no.

| Environment variable | Meaning | |---|---| | ARGUS_DATA_DIR | Data directory (default ~/.argus) | | ARGUS_SECRET_KEY | Passphrase for encrypting stored secrets (otherwise a key file is generated) | | ARGUS_CONCURRENCY | Reviews that run in parallel, a whole number of at least 1 (default 2) | | ARGUS_ADMIN_EMAIL, ARGUS_ADMIN_PASSWORD | Create this admin at start-up if it does not exist | | ARGUS_ALLOW_OPEN=1 | Serve without sign-in while there are no users (see above) | | ARGUS_ALLOWED_HOSTS | Extra host names the dashboard is reached by | | ARGUS_TRUST_PROXY=1 | Honour X-Forwarded-* headers from a reverse proxy | | ARGUS_SHUTDOWN_GRACE_MS | How long a stopping process lets running reviews finish before handing them back to the queue (default 25000). Keep it below your process manager's kill timeout (Docker stop_grace_period) | | ARGUS_GIT_TIMEOUT_MS | Timeout for git operations on the local mirror (default 300000) | | ARGUS_EXEC_DIR | Directory for test-sandbox workspaces (default: the system temp dir) | | ARGUS_SANDBOX_NETWORK | Docker network for the dependency install phase | | OPENROUTER_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENAI_COMPATIBLE_API_KEY | Provider keys, used when none is stored in the UI. Vendor keys only go to the vendor's default endpoint | | ARGUS_CLAUDE_BIN, ARGUS_CODEX_BIN, ARGUS_COPILOT_BIN | Paths to the claude, codex and copilot CLIs |

Teams and production

People and roles. Under Settings → Team & access, create the first admin; from then on everyone signs in with an email and password. Viewers see everything, maintainers also start, cancel and retry reviews and edit learnings and per-repository settings, admins manage integrations, models, keys, global settings and users. Listing and testing models, the GitHub App setup and listing an integration's remote repositories are admin-only too. In repository settings, maintainers cannot set the keys that only the operator may change (models, execution, analyzer configuration, ticket allow-lists, approvals, the cost cap; see Trust model); the server ignores them and the UI says which.

Storage. Everything lives in one SQLite database in the data directory, with a queue in it that survives restarts: a graceful shutdown hands unfinished reviews back to the queue, and a review left running by a process that crashed or was killed is marked failed at the next start. One Argus process serves one data directory; do not point several processes at the same one. To review more pull requests at once, raise ARGUS_CONCURRENCY.

Docker. docker build -t argus . builds a small image that runs as a non-root user. deploy/docker-compose.yml starts Argus with its data in a volume (copy deploy/.env.example to deploy/.env first; admin credentials are required). For the test sandbox, build with --build-arg DOCKER_CLI=true (adds only the static Docker client) and mount the Docker socket into the container. The container user then needs the socket's group (group_add), and because the daemon resolves bind mounts on the host, the workspace directory must exist at the same path on the host and in the container: point ARGUS_EXEC_DIR (and TMPDIR) at it. docker-compose.yml has the commented block. Socket access is root-equivalent on the host.

Upgrading. Stop Argus, back up the data directory (the database and secret.key, or keep ARGUS_SECRET_KEY), install the new version and start it again; database migrations run at start-up. Coming from 0.1.0, the shared dashboard password is gone: create an admin with the setup token printed at start-up (or ARGUS_ADMIN_EMAIL/ARGUS_ADMIN_PASSWORD).

npm. npm run pack:npm produces argus-review-<version>.tgz: one bundled CLI with the web UI, installable with npm install -g on any machine with Node 22.

GitHub App

On Repositories → Connect GitHub, choose GitHub App and click Create on GitHub. GitHub creates a private app with the exact permissions Argus needs and hands its key back to Argus. You then pick the repositories to install it on, and they are added automatically. Comments appear as the app's bot, tokens rotate hourly, and repositories added to the installation later appear on their own (when a public URL is set for webhooks). An existing app can be connected with its App ID and private key.

VS Code

npm run vscode:package builds apps/vscode/argus-vscode.vsix. Install it with Extensions → … → Install from VSIX, then set argus.command to the path of bin/argus (and argus.provider / argus.model, for example claude-code / claude-sonnet-5-5). argus.command and argus.extraArgs are machine-scoped: set them in user settings, a workspace cannot override them. Run Argus: Review staged changes from the command palette or the status bar: findings appear in the Problems panel with quick fixes for suggested code. npm run vscode:e2e runs the extension end to end in an isolated VS Code profile.

Review a pull request from the terminal

export OPENROUTER_API_KEY=…
export GITHUB_TOKEN=…           # or log in with `gh auth login`; GITLAB_TOKEN; BITBUCKET_TOKEN (+ BITBUCKET_USERNAME for API tokens)
argus review https://github.com/owner/repo/pull/42 --dry-run
argus review https://gitlab.com/group/project/-/merge_requests/7 --full
argus review https://bitbucket.org/workspace/repo/pull-requests/3 --focus "auth and sessions"

Review before you commit

argus local                    # staged changes
argus local --working          # everything uncommitted
argus local --base main        # the current branch since main
argus hook install             # run on every commit; ARGUS_FAIL_ON=major blocks the commit

CI

argus ci detects GitHub Actions, GitLab CI merge request pipelines, Bitbucket pull request pipelines and Azure Pipelines pull request builds, and it answers @argus comments in GitHub Actions. Ready-made workflow files are in the web UI under Server & CI, and for each repository added as reviewed in CI (see Connecting CI to the dashboard). They pin argus-review to the server's version, and the GitHub workflow only reacts to comments whose author_association is OWNER, MEMBER or COLLABORATOR. They call npx argus-review, which needs the package published to npm or a private registry. Until then, switch on Build Argus from source, which clones the repository (main; there are no version tags yet), runs npm ci and calls bin/argus ci. In CI, .argus.yml is read from the target branch like on the server, and API keys only go to endpoints configured outside the repository.

| Platform | Token | |---|---| | GitHub | GITHUB_TOKEN (provided by Actions; needs pull-requests: write and statuses: write, plus contents: write if Argus should resolve the threads of fixed findings, which GitHub ties to that permission) | | GitLab | GITLAB_TOKEN: a token with the api scope (the built-in job token cannot post comments) | | Bitbucket | BITBUCKET_TOKEN: a repository access token with pull request write | | Azure DevOps | SYSTEM_ACCESSTOKEN (the pipeline's $(System.AccessToken); allow the build service to contribute to pull requests) |

How Argus shows up. A GitHub App comments as <app>[bot] with its own logo: upload apps/web/public/brand/argus-logo.png under the app's Display information, and Argus reports a check run named argus with the same logo. On GitLab, a project or group access token comments as a bot account; when you connect it, Argus gives that bot the Argus logo (GitLab versions with PUT /user/avatar; a person's token is never touched). On Bitbucket, comments come from the access token's name with a generic picture, so Argus also publishes a Code Insights report named Argus, with its logo and the findings as line annotations. On every platform the summary comment starts with Argus's mark. For a dedicated bot user on a platform that falls back to Gravatar (GitLab self-managed, Bitbucket Data Center), give it an address such as [email protected] and register that address on Gravatar with the logo: the picture then follows the account everywhere.

Choosing a provider for CI

The generator on Server & CI has a provider and a model field (free text; the list only suggests). It sets ARGUS_PROVIDER and ARGUS_MODEL, installs the pinned CLI (@anthropic-ai/[email protected], @github/[email protected] or @openai/[email protected]) and lists the secrets to add. To change the model later without editing the file, set an ARGUS_MODEL variable in the CI settings (a GitHub repository variable, a GitLab CI/CD variable, a Bitbucket repository variable or an Azure pipeline or variable-group variable); it overrides the model in the file.

| Provider | Secret | |---|---| | OpenRouter | OPENROUTER_API_KEY | | Claude subscription | CLAUDE_CODE_OAUTH_TOKEN from claude setup-token | | GitHub Copilot | COPILOT_GITHUB_TOKEN: a fine-grained PAT owned by a personal account with "Copilot Requests" | | ChatGPT subscription (Codex) | ARGUS_CODEX_AUTH from argus codex-secret after codex login, plus ARGUS_SECRET_WRITE_TOKEN |

Codex logins refresh, so Argus writes the new login back to the CI secret after each run, also when the job is cancelled or times out. It can only update the current repository's own secret, so use one ChatGPT login per repository: run codex login and argus codex-secret separately for each repository and store the value as a repository-level (GitLab: project-level) secret, not an organization, group or workspace one. Two repositories sharing one login break each other: every refresh rotates the login, and the repository that did not refresh is left with a dead one. ARGUS_CODEX_AUTH is only used when a model in the review runs on Codex; with another provider it is ignored. ARGUS_SECRET_WRITE_TOKEN needs: GitHub, a fine-grained PAT with "Secrets: write"; GitLab, a project access token with api (Maintainer); Bitbucket, a repository access token with "Pipelines: Edit variables"; Azure, a PAT with "Variable Groups (Read, create, & manage)". Limits: Codex runs on private repositories only, one run at a time (the generated file serialises runs: queue: max on GitHub, resource_group on GitLab, concurrency-group on Bitbucket, lockBehavior: sequential plus an Exclusive lock check you add to the argus-codex environment on Azure), and on Azure the secret lives in a dedicated variable group (ARGUS_AZURE_VARIABLE_GROUP_ID) that holds nothing else.

Connecting CI to the dashboard

A CI run can pull its settings from an Argus dashboard and send each review back to it, so the reviews show up next to the ones the server ran. Under Repositories → Add → Reviewed in CI, enter the platform, host and owner/name (or the repository URL). Argus adds the repository and shows its repository token once, together with a pipeline generated for it (it points at the dashboard's public URL: the one set under Server & CI, else ARGUS_PUBLIC_URL, else the page's own address). A repository added through an integration has no CI token; to connect its CI, remove it and add it again as Reviewed in CI. Add two things to the repository's CI settings:

| Name | Kind | Value | |---|---|---| | ARGUS_URL | Variable (the generated file sets it in the job's environment; with your own file, set it there or as a CI variable) | The dashboard's public URL, for example https://argus.example.com. It must be https://; http:// is accepted only for localhost (any other http:// URL prints a warning, because the token and the results would travel unencrypted) | | ARGUS_TOKEN | Secret | The token shown when you added the repository (argus_…) |

argus ci talks to the dashboard only when both are set; with one of them missing it warns and reviews as before. The token only works for its own repository (another one gets 403 This token belongs to <owner>/<name>), and GitHub Actions masks it in the log. The repository's page in the dashboard shows the token's prefix, when it was created and last used, and has Regenerate token (shows a new token once; the old one stops working at once) and Revoke (CI then neither pulls settings nor sends results until an admin creates a new token). A rejected token (401 or 403) is reported in the job log, with what to fix.

Settings. Before the review, argus ci reads the repository's settings from the dashboard (global settings plus the repository's overrides). Layers, lowest first:

built-in defaults ─► global config file ─► CI variables and flags (ARGUS_PROVIDER, ARGUS_MODEL, …) ─► dashboard ─► .argus.yml (target branch, admin-only keys removed)

The dashboard layer is filtered in CI, so a dashboard can never make a CI job run commands or send secrets elsewhere: it may choose each model's provider and model and every review setting that is not admin-only, but never the execution and sandbox settings (sandbox, isolation, runtime, image, install and test commands, resources, timeouts), the analyzer configuration (semgrepConfig, analyzer timeouts), ticket allow-lists (tickets.allowedRepos, tickets.projectKeys), approvals, the cost cap, or any model's baseUrl or apiKey. It may switch execution.enabled, execution.runTests, execution.proveFindings and analyzers.enabled off, but not on: a true from the dashboard is ignored. Those stay in the CI flags, the CI environment or the global config file, and the job log lists any dashboard setting it ignored. API keys always come from the CI secrets.

Reviews off. When reviews are turned off for the repository in the dashboard, argus ci prints argus: skipped — Reviews are turned off for this repository in the Argus dashboard, posts nothing to the pull request, sends nothing to the dashboard and exits 0. The server also refuses results for such a repository (409 Reviews are turned off for this repository).

Results. After the review, skip or failure (also for @argus commands), argus ci sends the result, gzip-compressed, to POST /api/ci/reviews. The dashboard shows it as a CI review with a View CI run link; it cannot be retried or cancelled from the dashboard. The findings' outcomes (open, fixed, accepted, resolved, dismissed) are recorded like those of server reviews. Send summary only on the repository's page (admins) keeps only the outline (counts, titles and locations of findings, timings and usage) and leaves explanations, suggested fixes, code and the summary text on the pull request; the server enforces it on everything it stores, whatever the client sends. Results stored before the switch was turned on stay as they were stored.

Waits. Reading the settings waits at most 30 s and sending the result at most 30 s, retrying network errors, 5xx and 429 with 1 s, 2 s, 4 s, … backoff (401, 403, 409, 413 and an answer over 1 MB are final). If the settings cannot be read, the review runs with the CI settings only; if the dashboard rejected the token while reading them (401 or 403), the result is not sent either. Nothing the dashboard does changes the job's exit code. The generated files start a background curl to $ARGUS_URL/api/health at the start of the job, so a dashboard that sleeps when idle is awake by the time the review ends. The server accepts bodies up to 32 MiB, compressed or not (413 above that).

The Docker sandbox needs Docker in the job. GitHub and Azure hosted Ubuntu agents have it. The GitLab file adds a docker:27-dind service (the runner must be privileged and x86_64; gitlab.com saas-linux runners are, because the job downloads the x86_64 Docker CLI). The GitLab file also sets ARGUS_EXEC_DIR inside the project because dind cannot see /tmp. Do not mark any Argus variable on GitLab Protected, or it will not reach merge request pipelines on unprotected branches. The Bitbucket file uses services: [docker] and Runtime v3; without Runtime v3 the sandbox is skipped and the AI review still runs. Plan availability of Runtime v3 and concurrency-group is not verified.

Blocking merges

Every review sets an argus commit status on the pull request's head commit (on Azure DevOps a pull request status argus/review). To block merging until Argus passes, make it required:

| Platform | Where | |---|---| | GitHub | Branch protection or ruleset → Require status checks → argus | | GitLab | Settings → Merge requests → "Pipelines must succeed" (external statuses count) | | Bitbucket Cloud | Branch restrictions → Require passing builds | | Bitbucket Server / Data Center | Repository settings → Required builds → argus | | Azure DevOps | Branch policies → Status checks → Add argus/review |

The token Argus uses needs permission to set statuses: GitHub statuses: write (the GitHub App manifest and the generated Actions workflow include it), GitLab the api scope, Azure DevOps "Contribute to pull requests". If a token may not set statuses, the review still runs and the summary says so. In CI, --fail-on <severity> also fails the job itself.

Change the threshold with review.status.failOn (critical, major or minor), or turn statuses off with review.status.enabled: false. Only the operator can change these; .argus.yml cannot.

Using a Claude, ChatGPT or Copilot subscription

Choose the provider Claude subscription (Claude Code), ChatGPT subscription (Codex) or GitHub Copilot. Argus runs the official CLI in headless mode (claude -p --json-schema …, codex exec --output-schema …, copilot) in a read-only checkout, so reviews count against your plan instead of API billing. Usage limits of your plan apply.

  • Claude Code and Codex: log in once with claude or codex login on the machine that runs Argus.
  • GitHub Copilot: the Copilot CLI gets only read-only tools (view, glob, grep). Log in with copilot login, or set COPILOT_GITHUB_TOKEN (or GH_TOKEN) to a fine-grained personal access token with the "Copilot Requests" permission. GITHUB_TOKEN is only used inside GitHub Actions; on a server it is Argus's own GitHub credential and is never handed to Copilot. The dashboard can't check a copilot login and shows the login as unknown until you set a token. The model is free text (for example auto, claude-sonnet-5.5, gpt-6-luna or gemini-3.8-flash); Copilot offers Claude, GPT and Gemini families.

In a company. Subscription plans belong to a person and have personal usage limits. They suit argus local, the pre-commit hook and small teams. Before running one plan as the reviewer for a whole team on a server, check the provider's terms. For a shared server, an API key or a company gateway that speaks the OpenAI API (provider openai-compatible with a base URL) is the safer choice, and review.maxCostUsd keeps each review bounded.

Configuration

Settings come in layers: built-in defaults, then global settings (UI), then repository overrides (UI), then .argus.yml in the repository, then command-line flags. argus init writes a starter file, and every repository page in the UI can export its effective settings as YAML.

Trust model

A pull request author must not be able to change how Argus reviews their pull request, so .argus.yml and the guideline files are read from the target (base) branch, never from the pull request's head. What changes there takes effect after it is merged.

A repository file may only tune a review (allow-list; anything else is dropped and listed in the summary comment):

  • review: language, profile, severity and confidence floors, categories, suggestions, agent prompts, incremental; numeric limits (maxComments, maxFiles, maxCostUsd, passes, steps, …) only lower than the operator's; extra stages (verification, cross-file, voting, agent, auto-resolve, adaptive feedback) can only be turned off
  • summary: presentation keys; applyLabels only off, updateDescription only towards never (append > when-empty > never)
  • files: include/exclude, guideline files; code graph and bug history only off; contextDepth only lower (related > files > diff); maxContextChars lower only
  • autoReview: turn off, add ignored title keywords and authors; labels/baseBranches only when the operator set none
  • chat.mention (one word, 2–50 characters), and turning off chat, learning from feedback, analyzers, tickets and test execution (analyzers.disabled adds to the operator's list)
  • guidelines, pathInstructions, rules, learnings

Operator-only (global settings, or a repository's settings saved by an admin): models (providers, endpoints, keys), execution (sandbox, isolation, runtime, image, install/test commands, resources, timeouts), analyzer configuration (semgrepConfig, timeouts), review.examples.paths, review.approveWhenClean, review.requestChangesOn, tickets.allowedRepos / projectKeys, and anything that raises cost or turns on work the operator turned off. Maintainers editing repository settings in the UI cannot set the operator-only keys either.

argus local reads .argus.yml from your working tree: it is your own checkout.

models:
  review: { provider: openrouter, model: anthropic/claude-sonnet-5.5 }
  summary: { provider: openrouter, model: anthropic/claude-haiku-4.5 }
review:
  profile: chill            # quiet | chill | assertive
  minSeverity: minor        # critical | major | minor | nitpick
  minConfidence: 0.6
  maxComments: 30
  requestChangesOn: never   # never | critical | major
  agent: { enabled: true, maxSteps: 8, verify: true }
  voting: { enabled: true, passes: 3, scope: risky, maxFiles: 6, doubleCheckCritical: true }
analyzers:
  enabled: true
  disabled: [go-vet]
  semgrepConfig: [p/default, p/owasp-top-ten]
files:
  exclude: ["docs/**"]
guidelines: |
  All handlers validate input with zod.
pathInstructions:
  - path: "src/billing/**"
    instructions: "Amounts are integer cents; flag any floating point math."
rules:
  - id: no-sql-concatenation
    title: No SQL built from strings
    description: Use parameterized queries only.
    severity: critical

Argus can also:

  • Use past bug fixes as context. Commits that fixed bugs in the changed files are shown to the reviewer.
  • Learn from past human reviews. argus learn <repo-url>, or Learn from past reviews on a repository page, turns the conventions your reviewers keep asking for into suggested learnings.
  • Cache identical model answers, code-graph symbols and Docker dependency installs, and report time per stage.

A syntax-tree code graph (tree-sitter: TypeScript, JavaScript, Python, Go, Java, Rust, Ruby, PHP, C#, C++) gives the reviewer real callers with the function they sit in, definitions, implementations and the transitive impact of a change.

Files are routed by risk: formatting-only and trivial changes go to an optional light model without exploration, and high-risk files get extra voting passes. review.maxCostUsd (default $5) caps the spend of one review on paid APIs, and review.timeoutMinutes (default 30) stops a review that runs too long. When a provider reports no cost, it is estimated from the token counts, and calls in flight are counted against the cap before they finish. Local and private-network endpoints, openai-compatible endpoints with a custom base URL, and the claude/codex CLIs on a subscription count as free; set inputPricePerMTok and outputPricePerMTok on a model to price it yourself. A platform rate limit that resets more than a minute away fails the review with a rate-limit error instead of waiting.

Linked tickets

Issues of the pull request's own repository are always read. Issues of any other repository, including other repositories of the same organization, group or workspace, are only read when they match tickets.allowedRepos (owner/name, globs allowed; acme/* allows the whole organization). Jira and Linear tickets are only read for the project keys in tickets.projectKeys; with the list empty, none are fetched. Both lists are operator-only.

Test sandbox

execution.sandbox: auto (the default) uses Docker and skips test execution when Docker is not available. Dependencies are installed with network access; tests and proofs run without it. Package-manager caches are Docker volumes scoped per repository, mounted only for the cached install of unchanged dependency files; any other install (changed dependencies, a custom command, the project's own package) runs without them, so pull request code cannot plant packages for later reviews. Installed third-party dependencies are cached in one volume per lockfile, only for pull requests that don't change a manifest or lockfile, and only with the auto-detected install command (a custom installCommand is never cached). The project's own Python package is installed afterwards, outside the cache. The install phase blocks cloud metadata host names; to block metadata IPs and private ranges too, create a network, set ARGUS_SANDBOX_NETWORK to it, and add DOCKER-USER firewall rules that drop its traffic to 169.254.169.254 and RFC 1918 addresses. sandbox: host runs the project's commands directly on the Argus machine with a scrubbed environment; it is an explicit opt-in for trusted repositories only.

Run argus analyzers to see which linters and scanners are installed. --no-agent, --no-voting, --passes <n> and --no-analyzers switch the depth stages per run.

Cost scales with pull-request size. With every stage on, a small PR costs about $0.10 on Claude Sonnet through OpenRouter, and a large one (around 900 changed lines against 1,000+ line files) costs $1-1.50. Every stage can be turned off under Depth & analysis.

Chat commands

Reply to any Argus comment, or mention @argus in a pull request:

review · full review · review focus <topic> · summary · pause · resume · ignore · resolve · remember <convention> · configuration · help

Anyone can ask questions and read help. review, full review, review focus, summary, pause, resume and ignore need write access to the repository or being the pull request's author. resolve, remember and configuration need write access. If the permission lookup fails, Argus treats the commenter as having no access. The lookup needs:

| Platform | Permission lookup | |---|---| | GitHub | The commenter's collaborator permission on the repository | | GitLab | Project membership | | Bitbucket Cloud | A token that can read the workspace's repository permissions (group grants included) | | Bitbucket Server | A token with repository or project admin; permissions granted only through groups are not visible | | Azure DevOps | The commenter's effective Git permissions on the repository (Contribute = write, Manage permissions = admin, group grants included); the token needs the Identity (Read) and Security (Manage) scopes, otherwise only the pull request's author can use the author commands |

When someone with write access corrects a finding or uses remember, Argus stores the lesson as a learning scoped to the relevant paths. On the server it arrives pending approval (disabled): a maintainer or admin approves it under Learnings before later reviews apply it. In CI, Argus replies with the .argus.yml snippet instead. The server handles at most 10 chat comments per pull request per 10 minutes.

Development

npm test                       # unit and integration tests
npm run typecheck
npm run dev:server             # API on :4747 with reload
npm run dev:web                # UI on :5317, proxied to the API

Measuring quality

npm run eval                                          # 10 planted-bug PRs (recall and precision)
npm run eval:mine -- --repo https://github.com/sindresorhus/ky --limit 10
npm run eval:mined -- evals/mined/*.json --sample 9 --save evals/results/run.json   # one case per repository
npm run eval:mined -- evals/mined/*.json --save evals/results/full.json --resume      # all 99, resumable
npm run eval:compare -- evals/baselines/claude-sonnet-5-5-sample9.json evals/results/run.json
npm run eval:analyze -- evals/results/run.json        # why each bug was missed, and the top fixes

The eval runners use the claude-code provider (your Claude subscription) by default and stop paid API calls after --max-cost dollars (default 1). Cases that fail to run count as misses. eval:mined takes its judge from --judge-provider/--judge-model or ARGUS_EVAL_JUDGE=provider/model and warns when the judge is the model under review. ARGUS_DOCKER_TESTS=1 npm test also runs the Docker execution tests.

eval:mine uses the SZZ method. It finds bug-fix commits, blames the lines each fix changed back to the commit that introduced them, and stores that commit as a pull request together with the later fix. eval:mined reviews each introducing commit as if it were a new PR. An LLM judge then decides whether any finding names the same bug the fix addressed. evals/mined/ has 99 cases from ky, got, axios (TypeScript and JavaScript), click, flask, httpx (Python), cobra, chi (Go) and gson (Java). These bugs were subtle enough to get past the maintainers, so the scores are much lower than on planted bugs and show real progress more honestly. Ablation flags (--no-agent, --no-voting, --no-analyzers, --no-verify) work on both runners.

Layout: packages/core (engine, platforms, providers), apps/server (CLI, API, webhooks, queue), apps/web (React UI). Design notes are in docs/design.md.