When Claude rate-limits, automatically switch to Gemini. When that fails, run your own script.
Adversarial Multi-Agent Orchestration Tool for AI-assisted development
WARNING: This tool launches AI agents that run with full access to your codebase and system. Agents can read, create, modify, and delete files autonomously. By default, agents run with
--dangerously-skip-permissions, which bypasses all safety prompts. Review your agent prompts and configuration before runningcrew start. See SECURITY.md for details.
crew provides two distinct modes for AI agent orchestration:
| Command | Mode | Use Case |
|---|---|---|
design |
Design-Review | Refine ideas into polished design docs |
crew |
Parallel Agents | Run multiple AI agents for debugging/optimization |
brew tap garnetlyx/crew
brew install crewgit clone https://github.com/garnetlyx/crew ~/dev/crew
cd ~/dev/crew
./install.shThis creates symlinks in ~/.local/bin. If not already in PATH, add to your shell config:
export PATH="$HOME/.local/bin:$PATH"To uninstall:
cd ~/dev/crew
./uninstall.sh
# Or: brew uninstall crewRequires:
- Bash 4+
yqfor YAML parsing:brew install yq- An AI CLI:
claude,codex,opencode,gemini, oraider
Supported platforms:
- macOS (primary, actively developed)
- Linux (tested)
- Windows WSL (untested, should work)
Before running crew start, verify the following:
- Git clean state — commit or stash all work; agents will modify files
- Review prompts — read every file in
.crew/prompts/before agents use them - Review
crew.yaml— confirm each agent'scommandandenvfields look correct - No secrets in config — API keys go in shell env (
export ANTHROPIC_API_KEY=...), never increw.yaml -
.gitignorecovers runtime files —.crew/logs/,.crew/run/should be ignored - Understand
--dangerously-skip-permissions— agents bypass all safety prompts and can read/write/delete any file
Tip: Run
crew validateto check config syntax before starting agents.
Turn ideas into refined design documents through automated Writer ⇄ Reviewer loops.
# Initialize with your idea
design init "A CLI tool for managing container deployments"
# Start design-review loop
design review
# Check status
design status┌──────────────┐ trigger ┌──────────────┐
│ Plan Writer │ ──────────────→│ Reviewer │
│ Agent │ │ Agent │
└──────────────┘ └──────────────┘
↑ │
│ trigger (if !pass) │ pass?
└───────────────────────────────┘
- pass: Reviewer approves the plan
- stale: Plan unchanged for 2 iterations
- conflict: Same issues repeat 3+ times
.design/
├── design.yaml # Config
├── idea.txt # Your initial idea
├── plan.md # Current plan
├── review.md # Current review
└── history/ # All iterations
Run multiple AI agents in parallel for continuous codebase improvement.
# Initialize in your project
crew init
# Start all agents
crew start
# Start specific agents
crew start QA DEV JANITOR
# Monitor real-time
crew monitor
# View logs
crew logs QA
> **Tip**: For long-running tasks (like full test suites), log output may appear "stuck" due to buffering. The log will update in a large chunk once the command completes.
# Stop all
crew stopEdit .crew/crew.yaml:
project: my-project
check_interval: 30
agents:
- name: QA
icon: 🔴
type: claude
prompt: prompts/qa.txt
interval: 10
timeout: 600
- name: DEV
icon: 🔵
type: claude
prompt: prompts/dev.txt
- name: JANITOR
icon: 🟢
type: claude
prompt: prompts/janitor.txt
interval: 10
timeout: 600
> **Note**: Changes to `crew.yaml` (including `interval` and `env` variables) require a restart of the affected agents to take effect. Run `crew restart [AGENT]` to apply changes.If you prefer JSON over YAML, create .crew/crew.json instead. The JSON format uses python3 (built-in json module, no pip install needed) and supports the same fields:
{
"project": "my-project",
"check_interval": 30,
"agents": [
{
"name": "QA",
"type": "claude",
"prompt": "prompts/qa.md",
"interval": 10,
"timeout": 600
}
]
}YAML takes priority when both .crew/crew.yaml and .crew/crew.json exist. JSON config requires python3 to be available.
Get started quickly with preset configurations:
# List available templates
crew init --list-templates
# Initialize with a template
crew init --template code-review| Template | Agents | Use Case |
|---|---|---|
code-review |
QA + DEV | Adversarial testing and bug fixing |
refactor |
DEV + JANITOR | Code improvement with doc maintenance |
security-audit |
QA + DEV | Vulnerability probing and patching |
docs |
DEV + JANITOR | Documentation writing and consistency |
full |
QA + DEV + JANITOR | All agents running together |
.crew/
├── crew.yaml # Config
├── prompts/ # Agent prompts
├── logs/ # Agent logs
└── run/ # PID files
crew uses a plugin system for CLI abstraction. Each supported CLI has a plugin that handles prompt delivery and execution.
| Plugin | CLI | Install |
|---|---|---|
claude |
Claude Code | npm install -g @anthropic-ai/claude-code |
codex |
OpenAI Codex | npm install -g @openai/[email protected] (see Codex notes) |
opencode |
OpenCode | go install github.com/opencode-ai/opencode@latest |
gemini |
Google Gemini | pip install google-gemini-cli |
aider |
Aider | pip install aider-chat |
List installed plugins:
crew pluginsCreate a .sh file in .crew/cli.d/ (project-local) or ~/.crew/cli.d/ (global):
#!/bin/bash
# .crew/cli.d/myagent.sh
cli_myagent_check() {
command_exists myagent
}
cli_myagent_run() {
local prompt_file="$1"
local working_dir="$2"
(cd "$working_dir" && myagent --auto < "$prompt_file")
}
cli_myagent_run_prompt() {
local prompt="$1"
local working_dir="$2"
(cd "$working_dir" && echo "$prompt" | myagent --auto)
}Then use type: myagent in crew.yaml.
Use the env field in .crew/crew.yaml to configure per-agent environment variables for different providers:
agents:
- name: DEV
type: claude
prompt: prompts/dev.md
env:
ANTHROPIC_BASE_URL: https://openrouter.ai/api/v1
ANTHROPIC_MODEL: anthropic/claude-sonnet-4-20250514| Provider | ANTHROPIC_BASE_URL |
|---|---|
| Anthropic (default) | https://api.anthropic.com |
| OpenRouter | https://openrouter.ai/api/v1 |
| Self-hosted | http://localhost:8080/v1 |
IMPORTANT: Codex CLI v0.105.0+ dropped
wire_api = "chat"support, which is required by most third-party OpenAI-compatible providers. Use v0.80.0 when working with non-OpenAI models:npm install -g @openai/[email protected]
The codex plugin supports CODEX_* environment variables for configuring custom model providers. These are automatically translated into -c flags passed to the codex CLI:
| Variable | Description | Example |
|---|---|---|
CODEX_MODEL |
Model name | qwen3.5-plus |
CODEX_PROVIDER |
Provider identifier | dashscope |
CODEX_PROVIDER_NAME |
Human-readable name (defaults to CODEX_PROVIDER) |
DashScope |
CODEX_BASE_URL |
Provider API base URL | https://coding.dashscope.aliyuncs.com/v1 |
CODEX_WIRE_API |
Wire protocol: chat or responses |
chat |
CODEX_API_KEY_ENV |
Env var name holding the API key (default: OPENAI_API_KEY) |
OPENAI_API_KEY |
Example crew.yaml for codex with DashScope:
agents:
- name: DEV
type: codex
prompt: prompts/dev.md
env:
CODEX_MODEL: qwen3.5-plus
CODEX_PROVIDER: dashscope
CODEX_BASE_URL: https://coding.dashscope.aliyuncs.com/v1
CODEX_WIRE_API: chat
OPENAI_API_KEY: ${QWC_API_KEY} # set in .crew/.env
fallback:
- label: minimax
type: codex
env:
CODEX_MODEL: MiniMax-M2.5
CODEX_PROVIDER: minimax
CODEX_BASE_URL: https://api.minimaxi.com/v1
CODEX_WIRE_API: chat
OPENAI_API_KEY: ${MINIMAX_API_KEY}WARNING: Never put API keys in
crew.yamlif it's committed to git.
Set API keys in .crew/.env (git-ignored) or your shell environment:
export ANTHROPIC_API_KEY="sk-..."
export OPENAI_API_KEY="sk-..."Multiple projects can share a single environment configuration. crew searches for .env files in the following order:
- Global:
~/.crew/.env - Parent:
.crew/.envor.design/.envin any parent directory (recursive) - Local:
.crew/.envor.design/.envin the current project
Values are merged, with local project settings taking the highest priority.
When an agent fails repeatedly (reaching max_restarts), it automatically falls back to the next level in its fallback chain. Each level can change the CLI type, env vars, or both.
flowchart LR
A[Primary] -->|Fails max_restarts| B[Fallback 1]
B -->|Fails| C[Fallback 2]
C -->|Fails| D[Exhausted / Stop]
A -.->|Success| A
B -.->|Success| B
C -.->|Success| C
- Each level retries up to its
max_restarts(default: 5) with exponential backoff - On success, the agent stays at that level (does not revert to primary)
- After all levels are exhausted, the agent stops (
.crew/run/<name>.exhausted) - Fallback-level
envvars are merged on top of agent-level env — only override what changes - Use
crew restart AGENTto reset the fallback chain and start from primary crew statusshows the current active fallback level
Stay on the same CLI tool but step down through cheaper models or providers:
# opus (best) → sonnet (balanced) → 3rd party (cheapest)
- name: QA
type: claude
max_restarts: 5
env:
ANTHROPIC_MODEL: claude-opus-4-20250514
ANTHROPIC_API_KEY: ${ANT_API_KEY}
fallback:
- label: sonnet-fallback
type: claude
max_restarts: 3
env:
ANTHROPIC_MODEL: claude-sonnet-4-20250514 # API key inherited
- label: openrouter-fallback
type: claude
max_restarts: 3
env:
ANTHROPIC_BASE_URL: ${OPENROUTER_ANT_URL}
ANTHROPIC_MODEL: ${OPENROUTER_ANT_MODEL}
ANTHROPIC_API_KEY: ${OPENROUTER_ANT_KEY}Cascade through entirely different CLI tools for maximum resilience:
# claude → codex → gemini → local LLM (self-hosted, no API cost)
- name: DEV
type: claude
max_restarts: 5
env:
ANTHROPIC_API_KEY: ${ANT_API_KEY}
fallback:
- label: codex-openai
type: codex
max_restarts: 3
env:
OPENAI_API_KEY: ${OPENAI_API_KEY}
- label: gemini-google
type: gemini
max_restarts: 3
- label: local-llm
type: codex
max_restarts: 3
env:
CODEX_MODEL: ${LOCAL_OAI_MODEL}
CODEX_PROVIDER: local
CODEX_BASE_URL: ${LOCAL_OAI_URL}
CODEX_WIRE_API: chat
OPENAI_API_KEY: ${LOCAL_OAI_KEY}When all AI tools fail, run a custom shell script as last resort — send notifications, trigger CI/CD, or run non-AI automation:
# claude → opencode → notify team via script
- name: JANITOR
type: claude
max_restarts: 5
fallback:
- label: opencode-backup
type: opencode
max_restarts: 3
- label: notify-team
command: ./scripts/notify.sh # sends SMS/Slack/PagerDuty alert
max_restarts: 1See
templates/crew.yaml.examplefor a complete annotated configuration.
| Variable | Description |
|---|---|
CREW_AGENT |
Override default agent type (any installed plugin) |
ANTHROPIC_BASE_URL |
Override API endpoint for Claude CLI |
ANTHROPIC_MODEL |
Override model for Claude CLI |
ANTHROPIC_API_KEY |
API key for Claude CLI (set in shell, not config) |
OPENAI_API_KEY |
API key for Codex CLI (set in shell, not config) |
CODEX_MODEL |
Model name for Codex custom provider |
CODEX_PROVIDER |
Codex provider identifier (triggers -c flag injection) |
CODEX_BASE_URL |
Codex custom provider API base URL |
CODEX_WIRE_API |
Codex wire protocol: chat or responses |
GEMINI_API_KEY |
API key for Gemini CLI (set in shell, not config) |
DEBUG |
Set to 1 for verbose output |
cd ~/dev/my-app
design init "Add real-time collaboration with WebSockets"
design review --max-iter 3
# Result: .design/plan.md with refined designcd ~/dev/my-app
crew init
# Edit .crew/crew.yaml and prompts
crew start QA DEV JANITOR
crew monitor
# Agents run continuously, finding and fixing issues
crew stopIf you already have crew set up on another project:
cd ~/dev/crew # or wherever you cloned crew
git pull
./install.sh # re-creates symlinks, safe to re-runIn each project that uses crew:
crew stop # stop any running agents
rm -rf .crew/run/ # remove old PID files
rm -rf .crew/logs/ # remove old logs (optional)Breaking change: Commands with pipes or shell operators (e.g. cmd1 | cmd2)
no longer work in the command field. Use a wrapper script instead.
Before:
command: ANTHROPIC_MODEL=my-model claude --dangerously-skip-permissionsAfter:
command: claude --dangerously-skip-permissions
env:
ANTHROPIC_MODEL: my-modelThe command field is now optional. Use the type field instead:
Before:
command: claude --dangerously-skip-permissionsAfter:
type: claudeThe command field still works for backward compatibility and custom CLIs.
crew validate # check config syntax
crew start # test agents start correctly
crew status # confirm all running
crew stop # clean shutdownRequires bats-core:
# macOS
brew install bats-core
# Linux (apt)
sudo apt-get install batsRun tests:
# All unit tests
bats tests/unit/
# Specific test file
bats tests/unit/test_utils.bats
# Integration tests
bats tests/integration/MIT