argus-review 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +282 -2
- package/dist/cli.js +95795 -0
- package/dist/corpus/bug-corpus.json +1 -0
- package/package.json +21 -4
- package/web/assets/ReviewDetail-dZHWr7BD.js +30 -0
- package/web/assets/index-CZrrqEKD.js +168 -0
- package/web/assets/index-Cqbiqi7b.css +2 -0
- package/web/favicon.svg +1 -0
- package/web/index.html +22 -0
package/README.md
CHANGED
|
@@ -1,3 +1,283 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Argus
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
It runs four ways, from the same engine and settings:
|
|
6
|
+
|
|
7
|
+
| Mode | Command | Use it for |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Server + web UI | `argus serve` | Webhook-driven reviews, settings UI, review history, chat and learnings |
|
|
10
|
+
| One pull request | `argus review <url>` | Reviewing any PR or MR from your terminal |
|
|
11
|
+
| CI | `argus ci` | GitHub Actions, GitLab CI, Bitbucket Pipelines or Azure Pipelines, with no server |
|
|
12
|
+
| Local | `argus local` / `argus hook install` | Reviewing staged changes before you commit |
|
|
13
|
+
|
|
14
|
+
## How a review works
|
|
15
|
+
|
|
16
|
+
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.
|
|
17
|
+
2. **Intent.** The title, description, commits and an AI summary tell the reviewer what the change is supposed to do.
|
|
18
|
+
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.
|
|
19
|
+
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.
|
|
20
|
+
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.
|
|
21
|
+
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.
|
|
22
|
+
7. **Cross-file pass.** Catches contract changes whose callers were not updated.
|
|
23
|
+
8. **Secret scan.** Deterministic detection of keys and tokens in added lines.
|
|
24
|
+
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.
|
|
25
|
+
10. **Proof.** 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).
|
|
26
|
+
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.
|
|
27
|
+
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.
|
|
28
|
+
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).
|
|
29
|
+
|
|
30
|
+
Every dropped candidate is kept with its reason, and the web UI shows it under **Filtered out**.
|
|
31
|
+
|
|
32
|
+
## Requirements
|
|
33
|
+
|
|
34
|
+
- Node.js 22.12 or newer, and git
|
|
35
|
+
- 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
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
git clone <this repository> argus && cd argus
|
|
41
|
+
npm install # no .npmrc or --legacy-peer-deps needed
|
|
42
|
+
npm run build
|
|
43
|
+
npm link -w @argus/server # puts `argus` on your PATH
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
For development without building, use `bin/argus` (it runs the TypeScript sources directly).
|
|
47
|
+
|
|
48
|
+
## Server and web UI
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
argus serve # http://127.0.0.1:4747, data in ~/.argus
|
|
52
|
+
argus serve --port 8080 --host 0.0.0.0
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
In the UI:
|
|
56
|
+
|
|
57
|
+
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**.
|
|
58
|
+
2. **Repositories.** Connect GitHub, GitLab, Bitbucket or Azure DevOps with a token (the dialog lists the exact permissions), then add repositories.
|
|
59
|
+
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.
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
63
|
+
### Access and exposure
|
|
64
|
+
|
|
65
|
+
- **Loopback only, no users:** `argus serve` on `127.0.0.1` is open to requests made straight from the same machine: a loopback peer, a loopback `Host` header (`localhost`, `127.0.0.1`, `[::1]`, any port), no proxy headers (`X-Forwarded-For`, `Forwarded`, `X-Real-IP`, `X-Forwarded-Host`/`-Proto`, `Via`) and no public URL pointing elsewhere. Anything else is locked as below. A proxy or tunnel on the same host (nginx, `ssh -R`, socat, ngrok) must therefore not be relied on to look remote by itself: have it send `X-Forwarded-For` (nginx: `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`), or set a public URL in Settings → Server, which turns open mode off.
|
|
66
|
+
- **Reachable from the network (or through a proxy), no users:** the API is **locked** (`401 {setupRequired: true}`) until the first admin is created. Whenever there are no users and no shared password, the server prints a one-time setup token at start-up, whatever address it listens on (all replicas print the same token, which is stored in the database); 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. `ARGUS_ALLOW_OPEN=1` serves without sign-in on purpose, for example behind an authenticating proxy.
|
|
67
|
+
- **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.
|
|
68
|
+
- **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.
|
|
69
|
+
- **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.
|
|
70
|
+
|
|
71
|
+
Boolean variables accept `1`/`true`/`yes` and `0`/`false`/`no`.
|
|
72
|
+
|
|
73
|
+
| Environment variable | Meaning |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `ARGUS_DATA_DIR` | Data directory (default `~/.argus`) |
|
|
76
|
+
| `ARGUS_SECRET_KEY` | Passphrase for encrypting stored secrets (otherwise a key file is generated) |
|
|
77
|
+
| `ARGUS_CONCURRENCY` | Reviews that run in parallel per process (default 2) |
|
|
78
|
+
| `ARGUS_DATABASE_URL` | `postgres://…` to store everything in PostgreSQL instead of SQLite |
|
|
79
|
+
| `ARGUS_WORKER=0` | Serve the UI and webhooks only; reviews run on `argus worker` processes |
|
|
80
|
+
| `ARGUS_ADMIN_EMAIL`, `ARGUS_ADMIN_PASSWORD` | Create this admin at start-up if it does not exist |
|
|
81
|
+
| `ARGUS_ALLOW_OPEN=1` | Serve without sign-in even on a network address (see above) |
|
|
82
|
+
| `ARGUS_ALLOWED_HOSTS` | Extra host names the dashboard is reached by |
|
|
83
|
+
| `ARGUS_TRUST_PROXY=1` | Honour `X-Forwarded-*` headers from a reverse proxy |
|
|
84
|
+
| `ARGUS_SHUTDOWN_GRACE_MS` | How long a stopping process lets running reviews finish before handing them back to the queue (default 25000). Heartbeats continue meanwhile, so it may exceed the 90-second staleness window; keep it below the orchestrator's kill timeout (Kubernetes `terminationGracePeriodSeconds`) |
|
|
85
|
+
| `ARGUS_GIT_TIMEOUT_MS` | Timeout for git operations on the local mirror (default 300000) |
|
|
86
|
+
| `ARGUS_CHAT_RATE_LIMIT` | Chat comments handled per pull request per 10 minutes (default 10) |
|
|
87
|
+
| `ARGUS_WEBHOOK_MAX_BYTES` | Largest accepted webhook body (default 5 MB) |
|
|
88
|
+
| `ARGUS_EXEC_DIR` | Directory for test-sandbox workspaces (default: the system temp dir) |
|
|
89
|
+
| `ARGUS_SANDBOX_NETWORK` | Docker network for the dependency install phase |
|
|
90
|
+
| `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 |
|
|
91
|
+
| `ARGUS_CLAUDE_BIN`, `ARGUS_CODEX_BIN`, `ARGUS_COPILOT_BIN` | Paths to the `claude`, `codex` and `copilot` CLIs |
|
|
92
|
+
|
|
93
|
+
## Teams and production
|
|
94
|
+
|
|
95
|
+
**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](#trust-model)); the server ignores them and the UI says which.
|
|
96
|
+
|
|
97
|
+
**PostgreSQL and workers.** Set `ARGUS_DATABASE_URL` and every Argus process shares one database. The queue lives in it: `argus serve --no-worker` serves the UI and webhooks, and any number of `argus worker` processes claim reviews (`FOR UPDATE SKIP LOCKED`), send heartbeats and pick up cancellations. A review whose worker dies is marked failed after 90 seconds. All processes need the same `ARGUS_SECRET_KEY`.
|
|
98
|
+
|
|
99
|
+
**Docker.** `docker build -t argus .` builds a small image that runs as a non-root user. `deploy/docker-compose.yml` starts PostgreSQL, the web process and two workers (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 workers. The worker 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.
|
|
100
|
+
|
|
101
|
+
**Kubernetes.** The image is not published: build and push it (`docker build -t registry.example.com/argus:<version> .`) and set `image.repository`; `image.tag` defaults to the chart's `appVersion`. `helm install argus deploy/helm/argus --set secret.secretKey=… --set postgres.password=… --set secret.adminEmail=… --set secret.adminPassword=…` deploys the web process, the workers and (optionally) PostgreSQL; the chart refuses to render without admin credentials unless `allowOpen=true`. Point `secret.databaseUrl` at a managed database with `postgres.enabled=false`. `web.replicas` can be raised: sessions, the setup token and the GitHub App setup state are signed or stored in the database. With the ingress enabled, `ARGUS_ALLOWED_HOSTS` and `ARGUS_TRUST_PROXY` are set from it. `worker.dind.enabled` adds a privileged Docker-in-Docker sidecar for the test sandbox; it needs a worker image built with `--build-arg DOCKER_CLI=true` (`worker.image`), shares the exec directory with the sidecar, and cannot be combined with `worker.runtimeClassName`. `web.extraEnv` and `worker.extraEnv` pass further variables.
|
|
102
|
+
|
|
103
|
+
**Upgrading from an earlier version.** All sessions are invalidated, so everyone signs in again; stored secrets still decrypt. Repository settings saved before the upgrade are not known to be admin-written, so their admin-only keys are ignored until an admin saves that repository's settings again. The test sandbox's old shared cache volumes (`argus-deps`, `argus-cache-*`) are no longer used and can be removed with `docker volume rm`. The upgrade folds duplicate queued reviews of the same pull request into one; during a rolling upgrade, processes still on the old version may briefly answer 500 when a second review of a pull request is queued while one is already waiting (that request is dropped; the queued review still runs), so upgrade all processes together where possible. Argus now recognises its own comments by its account (the token's user, or `<app-slug>[bot]` for a GitHub App); if that lookup fails, the review fails before posting anything and the next one tries again, rather than posting duplicate comments or a second summary. A loopback-bound server that has a public URL set, or is reached through a proxy, now requires sign-in (see [Access and exposure](#access-and-exposure)).
|
|
104
|
+
|
|
105
|
+
**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.
|
|
106
|
+
|
|
107
|
+
## GitHub App
|
|
108
|
+
|
|
109
|
+
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.
|
|
110
|
+
|
|
111
|
+
## VS Code
|
|
112
|
+
|
|
113
|
+
`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.
|
|
114
|
+
|
|
115
|
+
## Review a pull request from the terminal
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
export OPENROUTER_API_KEY=…
|
|
119
|
+
export GITHUB_TOKEN=… # or log in with `gh auth login`; GITLAB_TOKEN; BITBUCKET_TOKEN (+ BITBUCKET_USERNAME for API tokens)
|
|
120
|
+
argus review https://github.com/owner/repo/pull/42 --dry-run
|
|
121
|
+
argus review https://gitlab.com/group/project/-/merge_requests/7 --full
|
|
122
|
+
argus review https://bitbucket.org/workspace/repo/pull-requests/3 --focus "auth and sessions"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Review before you commit
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
argus local # staged changes
|
|
129
|
+
argus local --working # everything uncommitted
|
|
130
|
+
argus local --base main # the current branch since main
|
|
131
|
+
argus hook install # run on every commit; ARGUS_FAIL_ON=major blocks the commit
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## CI
|
|
135
|
+
|
|
136
|
+
`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**. 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.
|
|
137
|
+
|
|
138
|
+
| Platform | Token |
|
|
139
|
+
|---|---|
|
|
140
|
+
| GitHub | `GITHUB_TOKEN` (provided by Actions; needs `pull-requests: write`) |
|
|
141
|
+
| GitLab | `GITLAB_TOKEN`: a token with the `api` scope (the built-in job token cannot post comments) |
|
|
142
|
+
| Bitbucket | `BITBUCKET_TOKEN`: a repository access token with pull request write |
|
|
143
|
+
| Azure DevOps | `SYSTEM_ACCESSTOKEN` (the pipeline's `$(System.AccessToken)`; allow the build service to contribute to pull requests) |
|
|
144
|
+
|
|
145
|
+
### Choosing a provider for CI
|
|
146
|
+
|
|
147
|
+
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/claude-code@2.1.296`, `@github/copilot@1.0.95` or `@openai/codex@0.162.1`) 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.
|
|
148
|
+
|
|
149
|
+
| Provider | Secret |
|
|
150
|
+
|---|---|
|
|
151
|
+
| OpenRouter | `OPENROUTER_API_KEY` |
|
|
152
|
+
| Claude subscription | `CLAUDE_CODE_OAUTH_TOKEN` from `claude setup-token` |
|
|
153
|
+
| GitHub Copilot | `COPILOT_GITHUB_TOKEN`: a fine-grained PAT owned by a personal account with "Copilot Requests" |
|
|
154
|
+
| ChatGPT subscription (Codex) | `ARGUS_CODEX_AUTH` from `argus codex-secret` after `codex login`, plus `ARGUS_SECRET_WRITE_TOKEN` |
|
|
155
|
+
|
|
156
|
+
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.
|
|
157
|
+
|
|
158
|
+
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.
|
|
159
|
+
|
|
160
|
+
## Using a Claude, ChatGPT or Copilot subscription
|
|
161
|
+
|
|
162
|
+
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.
|
|
163
|
+
|
|
164
|
+
- **Claude Code and Codex:** log in once with `claude` or `codex login` on the machine that runs Argus.
|
|
165
|
+
- **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.
|
|
166
|
+
|
|
167
|
+
## Configuration
|
|
168
|
+
|
|
169
|
+
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.
|
|
170
|
+
|
|
171
|
+
### Trust model
|
|
172
|
+
|
|
173
|
+
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.
|
|
174
|
+
|
|
175
|
+
A repository file may only tune a review (allow-list; anything else is dropped and listed in the summary comment):
|
|
176
|
+
- `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, examples, function review, auto-resolve, adaptive feedback) can only be turned off
|
|
177
|
+
- `summary`: presentation keys; `applyLabels` only off, `updateDescription` only towards `never` (`append` > `when-empty` > `never`)
|
|
178
|
+
- `files`: include/exclude, guideline files; code graph and bug history only off; `contextDepth` only lower (`related` > `files` > `diff`); `maxContextChars` lower only
|
|
179
|
+
- `autoReview`: turn off, add ignored title keywords and authors; `labels`/`baseBranches` only when the operator set none
|
|
180
|
+
- `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)
|
|
181
|
+
- `guidelines`, `pathInstructions`, `rules`, `learnings`
|
|
182
|
+
|
|
183
|
+
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.
|
|
184
|
+
|
|
185
|
+
`argus local` reads `.argus.yml` from your working tree: it is your own checkout.
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
models:
|
|
189
|
+
review: { provider: openrouter, model: anthropic/claude-sonnet-5.5 }
|
|
190
|
+
summary: { provider: openrouter, model: anthropic/claude-haiku-4.5 }
|
|
191
|
+
review:
|
|
192
|
+
profile: chill # quiet | chill | assertive
|
|
193
|
+
minSeverity: minor # critical | major | minor | nitpick
|
|
194
|
+
minConfidence: 0.6
|
|
195
|
+
maxComments: 30
|
|
196
|
+
requestChangesOn: never # never | critical | major
|
|
197
|
+
agent: { enabled: true, maxSteps: 8, verify: true }
|
|
198
|
+
voting: { enabled: true, passes: 3, scope: risky, maxFiles: 6, doubleCheckCritical: true }
|
|
199
|
+
analyzers:
|
|
200
|
+
enabled: true
|
|
201
|
+
disabled: [go-vet]
|
|
202
|
+
semgrepConfig: [p/default, p/owasp-top-ten]
|
|
203
|
+
files:
|
|
204
|
+
exclude: ["docs/**"]
|
|
205
|
+
guidelines: |
|
|
206
|
+
All handlers validate input with zod.
|
|
207
|
+
pathInstructions:
|
|
208
|
+
- path: "src/billing/**"
|
|
209
|
+
instructions: "Amounts are integer cents; flag any floating point math."
|
|
210
|
+
rules:
|
|
211
|
+
- id: no-sql-concatenation
|
|
212
|
+
title: No SQL built from strings
|
|
213
|
+
description: Use parameterized queries only.
|
|
214
|
+
severity: critical
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Argus can also:
|
|
218
|
+
- **Hunt for bugs with property-based tests.** For the riskiest changed functions it writes property tests from their contract, runs them in Docker on the PR and on the base branch, and reports properties the change broke.
|
|
219
|
+
- **Get a second opinion.** `models.second` (or `--second codex/gpt-6-luna`) adds an independent reviewer from another model family; findings both models report gain confidence.
|
|
220
|
+
- **Use past bug fixes as context.** Commits that fixed bugs in the changed files are shown to the reviewer.
|
|
221
|
+
- **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.
|
|
222
|
+
- **Run CodeQL** for cross-file data flow when the `codeql` CLI is installed.
|
|
223
|
+
- **Cache** identical model answers, code-graph symbols and Docker dependency installs, and report time per stage.
|
|
224
|
+
|
|
225
|
+
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.
|
|
226
|
+
|
|
227
|
+
Files are routed by risk: formatting-only and trivial changes go to an optional light model without exploration, and high-risk files to an optional deep model with voting. `review.maxCostUsd` caps the spend of one review on paid APIs. 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.
|
|
228
|
+
|
|
229
|
+
### Linked tickets
|
|
230
|
+
|
|
231
|
+
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.
|
|
232
|
+
|
|
233
|
+
### Test sandbox
|
|
234
|
+
|
|
235
|
+
`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.
|
|
236
|
+
|
|
237
|
+
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.
|
|
238
|
+
|
|
239
|
+
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**.
|
|
240
|
+
|
|
241
|
+
## Chat commands
|
|
242
|
+
|
|
243
|
+
Reply to any Argus comment, or mention `@argus` in a pull request:
|
|
244
|
+
|
|
245
|
+
`review` · `full review` · `review focus <topic>` · `summary` · `pause` · `resume` · `ignore` · `resolve` · `remember <convention>` · `configuration` · `help`
|
|
246
|
+
|
|
247
|
+
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:
|
|
248
|
+
|
|
249
|
+
| Platform | Permission lookup |
|
|
250
|
+
|---|---|
|
|
251
|
+
| GitHub | The commenter's collaborator permission on the repository |
|
|
252
|
+
| GitLab | Project membership |
|
|
253
|
+
| Bitbucket Cloud | A token that can read the workspace's repository permissions (group grants included) |
|
|
254
|
+
| Bitbucket Server | A token with repository or project admin; permissions granted only through groups are not visible |
|
|
255
|
+
| 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 |
|
|
256
|
+
|
|
257
|
+
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 `ARGUS_CHAT_RATE_LIMIT` (default 10) chat comments per pull request per 10 minutes.
|
|
258
|
+
|
|
259
|
+
## Development
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
npm test # unit and integration tests
|
|
263
|
+
npm run typecheck
|
|
264
|
+
npm run dev:server # API on :4747 with reload
|
|
265
|
+
npm run dev:web # UI on :5317, proxied to the API
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Measuring quality
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
npm run eval # 10 planted-bug PRs (recall and precision)
|
|
272
|
+
npm run eval:mine -- --repo https://github.com/sindresorhus/ky --limit 10
|
|
273
|
+
npm run eval:mined -- evals/mined/*.json --sample 9 --save evals/results/run.json # one case per repository
|
|
274
|
+
npm run eval:mined -- evals/mined/*.json --save evals/results/full.json --resume # all 99, resumable
|
|
275
|
+
npm run eval:compare -- evals/baselines/claude-sonnet-5-5-sample9.json evals/results/run.json
|
|
276
|
+
npm run eval:analyze -- evals/results/run.json # why each bug was missed, and the top fixes
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
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.
|
|
280
|
+
|
|
281
|
+
`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.
|
|
282
|
+
|
|
283
|
+
Layout: `packages/core` (engine, platforms, providers), `apps/server` (CLI, API, webhooks, queue), `apps/web` (React UI). Design notes are in `docs/design.md`.
|