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):

bash
# macOS or Linux (Homebrew)
brew install adversarylabs/tap/adversary

Linux 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.

bash
# 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 --version

Windows — 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.

powershell
# 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 PATH

Verify the install

$adversary --version

Prefer 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.

bash
adversary login
adversary whoami

Headless 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:

bash
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 ../service

Catalog 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.

CommandPurpose
login / logout / whoamiAuthenticate with Adversary Labs and inspect the active profile.
search / list / outdatedBrowse local store + remote catalog; find packages that need upgrade.
pullInstall a package from the catalog or any OCI registry (fetches official signature when present).
runRun one or more adversaries (or auto-select) against a local repository path. Explicit refs expand adversary.yaml uses (composition) unless --no-compose.
trainGrade home-built packages against PR review history; draft and apply improvements (results inbox). Official catalog is jury-only.
initScaffold a TypeScript adversary project.
validateValidate a project with the canonical v1 manifest parser.
packPackage a project into the local content-addressable store.
pushPush a packed artifact to an OCI registry.
signAttach an official signature referrer (publishers / CI; end users do not need this).
inspectInspect a local project or installed store entry.
removeDelete installed packages from the local store (not the remote catalog).
storeLow-level store maintenance (check, gc, …).
version / completionPrint 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.

bash
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 json

Composition (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.

bash
# 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-compose

Comment 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).

bash
# 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.

bash
# 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).

FlagRole
--pathRepository root to review (default ".").
--base / --headGit refs for change scope. --base main implies --head HEAD.
--all-filesScan the whole target instead of inferred changes.
--allWith no refs: run every available adversary (skip detection).
--dry-run / --explainWith no refs: print selection without running.
--format text|json / --jsonReview output format (JSON is a versioned envelope).
--output-fileWrite results to a file; progress stays on the terminal.
--no-composeDo not expand adversary.yaml uses; run only the named refs.
--no-pullWith no refs: use only the local store.
--allow-unsafe-host-executionAllow host execution of an untrusted (unsigned) package.
--no-networkRequire network isolation (fails on HostExecutor).
--model-provider / --modelOverride LLM provider/model (analysis and GitHub voice rewrite).
--github-reviewPlan/post PR comments; enables voice rewrite when a model is configured.
--github-dry-runWith --github-review: plan only; no GitHub mutation.
--buildBuild 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

bash
adversary search dockerfile
adversary list
adversary list --outdated
adversary pull go/cli
adversary outdated
adversary remove go/cli:0.0.15

List 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).

bash
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.0

Official 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.

ConcernFlag / env
API endpoint--api-url / ADVERSARY_API_URL
Credential profile--profile
Default registryADVERSARY_REGISTRY_HOST / ADVERSARY_REGISTRY_NAMESPACE
Artifact data dirADVERSARY_DATA_DIR
Node binaryADVERSARY_NODE_PATH, then PATH
Model--model-provider, --model / ADVERSARY_MODEL_*
Telemetry opt-outDO_NOT_TRACK=1, ADVERSARY_NO_TELEMETRY=1, or ADVERSARY_TELEMETRY=0