CLI

Install the Doomer CLI, authenticate, and run the full command surface against the free catalog, private project 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 doomerlabs/tap/doomer

Linux and macOS — GitHub release archive

Download the matching .tar.gz from GitHub Releases. Assets look like doomer_<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/doomerlabs/doomer/releases
VERSION=2026.9.18
ARCH=amd64   # or arm64
OS=linux     # or darwin
ASSET="doomer_${VERSION}_${OS}_${ARCH}.tar.gz"
BASE="https://github.com/doomerlabs/doomer/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 doomer /usr/local/bin/doomer
doomer --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/doomerlabs/[email protected]

# B) Build a release-shaped binary (embeds official-prod public key)
git clone https://github.com/doomerlabs/doomer.git
cd doomer
git checkout 2026.9.18
go build -tags release -o doomer.exe .
# Put doomer.exe on your PATH

Verify the install

$doomer --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
doomer login
doomer whoami

Headless and CI options include doomer 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
doomer pull go/security

doomer run go/security --path .

# Or author and run a local project
doomer init my-adversary
cd my-adversary
npm ci && npm run build
doomer run . --path ../service

Catalog ids use domain/name form (for example go/security, ci/github-actions). Browse the live catalog at /adversaries.

Command reference

Login authenticates your account without selecting a project. Profiles separate accounts and API connections; --profile work selects the account. Project-specific commands will use --project my-project to select a project. Canonical flags live in the binary: doomer help <command>. Global flags: --api-url, --profile.

CommandPurpose
login / logout / whoamiAuthenticate with Doomer 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.

doomer 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
doomer login
doomer run --path .
# pulls accessible catalog packages (unless --no-pull),
# detects which apply to the review scope, and runs them

doomer run --dry-run --explain --path .
doomer run --all --all-files --path .
doomer 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)
doomer run lang/go --path ./service

# Persona pack (uses specialists; voice from entry agent/voice*)
doomer run local/torvalds-adversary --path ./app --github-review

# Local checkout as entry
doomer run ./torvalds-adversary --path ./app --github-review

# Skip expansion — only the named package
doomer 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
doomer 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 project’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

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

doomer train run
doomer train results ls
doomer train results inspect <id>
doomer 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
doomer search dockerfile
doomer list
doomer list --outdated
doomer pull go/cli
doomer outdated
doomer 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 doomer init. Node.js 22+ is required and managed by you (the CLI does not download Node).

bash
doomer init my-adversary --sdk typescript
cd my-adversary
npm ci && npm test && npm run build
doomer validate .
doomer pack .
doomer 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
Account connection 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