CLI
Install the Adversary CLI, authenticate, and run the full command surface against the free catalog, private team namespaces, or external registries.
Install
Packaged release binaries target macOS and Linux on amd64 and arm64. Windows is source-build supported but does not yet ship a packaged archive. Release builds embed the official-prod public key used to verify catalog signatures.
macOS and Linux — Homebrew
Recommended when you have Homebrew (including Linuxbrew):
# macOS or Linux (Homebrew)
brew install adversarylabs/tap/adversaryLinux and macOS — GitHub release archive
Download the matching .tar.gz from GitHub Releases. Assets look like adversary_<version>_linux_amd64.tar.gz (also linux_arm64, darwin_amd64, darwin_arm64). Verify checksums.txt before installing.
# Pick the latest CalVer tag from:
# https://github.com/adversarylabs/adversary/releases
VERSION=2026.7.30
ARCH=amd64 # or arm64
OS=linux # or darwin
ASSET="adversary_${VERSION}_${OS}_${ARCH}.tar.gz"
BASE="https://github.com/adversarylabs/adversary/releases/download/${VERSION}"
curl -fsSL -o "$ASSET" "$BASE/$ASSET"
curl -fsSL -o checksums.txt "$BASE/checksums.txt"
# Verify (GNU coreutils; on macOS: shasum -a 256 and compare manually)
sha256sum --check --ignore-missing checksums.txt
tar -xzf "$ASSET"
sudo install -m 755 adversary /usr/local/bin/adversary
adversary --versionWindows — build from source
There is no Windows .zip release yet. Use Go 1.24+ (or whatever the repo go.mod requires) and build with -tags release so the binary embeds the production signature public key.
# Windows has no packaged release archive yet (source + CI only).
# Install a recent Go toolchain, then either:
# A) go install (quick; version often reports "dev" — no release ldflags)
go install github.com/adversarylabs/[email protected]
# B) Build a release-shaped binary (embeds official-prod public key)
git clone https://github.com/adversarylabs/adversary.git
cd adversary
git checkout 2026.7.30
go build -tags release -o adversary.exe .
# Put adversary.exe on your PATHVerify the install
adversary --versionPrefer a stamped release version over dev when you need official catalog signature verification with the production keyring.
Authenticate
Catalog search and pull require sign-in so we can attribute usage. The public catalog is free — authentication is not a paywall.
adversary login
adversary whoamiHeadless and CI options include adversary login --device, --ci, and service-account tokens via --token-stdin. See Registry authentication.
Quick start
New here? Follow the getting started guide. Short version:
adversary pull go/security
adversary run go/security --path .
# Or author and run a local project
adversary init my-adversary
cd my-adversary
npm ci && npm run build
adversary run . --path ../serviceCatalog ids use domain/name form (for example go/security, ci/github-actions). Browse the live catalog at /adversaries.
Command reference
Canonical flags live in the binary: adversary help <command>. Global flags: --api-url, --profile.
| Command | Purpose |
|---|---|
| login / logout / whoami | Authenticate with Adversary Labs and inspect the active profile. |
| search / list / outdated | Browse local store + remote catalog; find packages that need upgrade. |
| pull | Install a package from the catalog or any OCI registry (fetches official signature when present). |
| run | Run one or more adversaries (or auto-select) against a local repository path. Explicit refs expand adversary.yaml uses (composition) unless --no-compose. |
| train | Grade home-built packages against PR review history; draft and apply improvements (results inbox). Official catalog is jury-only. |
| init | Scaffold a TypeScript adversary project. |
| validate | Validate a project with the canonical v1 manifest parser. |
| pack | Package a project into the local content-addressable store. |
| push | Push a packed artifact to an OCI registry. |
| sign | Attach an official signature referrer (publishers / CI; end users do not need this). |
| inspect | Inspect a local project or installed store entry. |
| remove | Delete installed packages from the local store (not the remote catalog). |
| store | Low-level store maintenance (check, gc, …). |
| version / completion | Print version; generate shell completions. |
adversary run
Review a local source tree. Pass one or more adversary references, or omit them to auto-select from the catalog and local store.
adversary login
adversary run --path .
# pulls accessible catalog packages (unless --no-pull),
# detects which apply to the review scope, and runs them
adversary run --dry-run --explain --path .
adversary run --all --all-files --path .
adversary run go/security security/secrets --path . --format jsonComposition (uses)
Explicit refs expand adversary.yaml uses transitively (language packs like lang/go, personas like torvalds). Detection runs on each member; GitHub comment voice stays on the entry package. See the SDK docs for the manifest field shape.
# Language pack (adversary.yaml uses → go/* specialists)
adversary run lang/go --path ./service
# Persona pack (uses specialists; voice from entry agent/voice*)
adversary run local/torvalds-adversary --path ./app --github-review
# Local checkout as entry
adversary run ./torvalds-adversary --path ./app --github-review
# Skip expansion — only the named package
adversary run lang/go --path ./service --no-composeComment voice
With --github-review, the CLI rewrites comment bodies using the package agent/voice.md (core rules + optional example few-shots). Voice is how it sounds; findings still carry technical depth. Under composition, the package you name on the CLI owns voice—not every specialist. Train apply banks human gold into the example-bank subsections (style only).
# Rewrite PR comments with package agent/voice.md (needs model provider)
export OPENAI_API_KEY=… # or provider-specific env
adversary run ./torvalds-adversary --path ./app --github-review --github-dry-run --model-provider openai --model gpt-4o-mini
# Voice resolve order: package agent/voice.md → train/voice.md → voice.md → CLI default
# Without model credentials, comments keep the deterministic template body.Train (home-built packages)
Improve your local adversaries from your team’s real PR reviews. Train grades local packages against human comments, optionally runs official catalog packages as a read-only jury, and writes an inbox of drafts. Only locals receive apply issues—never official catalog ids.
# From a home-built package root (has adversary.yaml)
export GH_TOKEN=… # or ADVERSARY_GITHUB_TOKEN / GITHUB_TOKEN
adversary train init --single-package
# edit adversary.train.yaml:
# sources.repos / sources.org OR discovery: author_reviews + authors_only
# official.enabled: true (jury; never trains official packages)
adversary train run
adversary train results ls
adversary train results inspect <id>
adversary train results apply <id>
# → docs/train-drafts/<id>.md + GitHub issue on the package remote
# Implement detection class + bank human gold in agent/voice.md (style only)Subcommands: train init, train run, train results ls|inspect|apply|dismiss, train status, train reset. Config: committed adversary.train.yaml; state: gitignored .adversary-train/. On apply, implement detection for the spirit class and bank human wording in agent/voice.md (style few-shots only).
| Flag | Role |
|---|---|
| --path | Repository root to review (default "."). |
| --base / --head | Git refs for change scope. --base main implies --head HEAD. |
| --all-files | Scan the whole target instead of inferred changes. |
| --all | With no refs: run every available adversary (skip detection). |
| --dry-run / --explain | With no refs: print selection without running. |
| --format text|json / --json | Review output format (JSON is a versioned envelope). |
| --output-file | Write results to a file; progress stays on the terminal. |
| --no-compose | Do not expand adversary.yaml uses; run only the named refs. |
| --no-pull | With no refs: use only the local store. |
| --allow-unsafe-host-execution | Allow host execution of an untrusted (unsigned) package. |
| --no-network | Require network isolation (fails on HostExecutor). |
| --model-provider / --model | Override LLM provider/model (analysis and GitHub voice rewrite). |
| --github-review | Plan/post PR comments; enables voice rewrite when a model is configured. |
| --github-dry-run | With --github-review: plan only; no GitHub mutation. |
| --build | Build a local adversary before running. |
Scope inference (when you omit --base/ --head/ --all-files): CI PR refs → worktree changes → feature branch vs default branch → whole tree. Selected scope is printed on stderr before execution.
Catalog lifecycle
adversary search dockerfile
adversary list
adversary list --outdated
adversary pull go/cli
adversary outdated
adversary remove go/cli:0.0.15List and search merge the local store with the remote catalog you can access. Status is installed, catalog, or outdated. Retired path styles are hidden; domain catalog ids remain.
Author and publish
Only the TypeScript SDK template is supported for adversary init. Node.js 22+ is required and managed by you (the CLI does not download Node).
adversary init my-adversary --sdk typescript
cd my-adversary
npm ci && npm test && npm run build
adversary validate .
adversary pack .
adversary push my-adversary:0.1.0 ghcr.io/acme/my-adversary:0.1.0Official catalog packages are signed in release CI after push. For private packages, any OCI registry works. See Distribution and Official signatures.
Trust and host execution
Local projects selected by filesystem path run on HostExecutor without friction. Installed packages need a verified official signature for the same. Unsigned packages are untrusted: interactive TTY prompt, or --allow-unsafe-host-execution in CI.
Details: Official signatures · Execution trust model.
Configuration
Precedence: command flags → environment → profile config → defaults.
| Concern | Flag / env |
|---|---|
| API endpoint | --api-url / ADVERSARY_API_URL |
| Credential profile | --profile |
| Default registry | ADVERSARY_REGISTRY_HOST / ADVERSARY_REGISTRY_NAMESPACE |
| Artifact data dir | ADVERSARY_DATA_DIR |
| Node binary | ADVERSARY_NODE_PATH, then PATH |
| Model | --model-provider, --model / ADVERSARY_MODEL_* |
| Telemetry opt-out | DO_NOT_TRACK=1, ADVERSARY_NO_TELEMETRY=1, or ADVERSARY_TELEMETRY=0 |