Otto is a simple CLI tool that autonomously runs AI coding agents in a loop. On each iteration, it launches an agent which picks a task from the beads system, works on it, then exits. Otto repeats this until no ready tasks remain.
Enable autonomous AFK (away from keyboard) coding by continuously running AI agents against a task queue. No complex orchestration—just a simple loop that lets agents work through tasks independently.
- Simple Loop: Runs agents until no ready beads remain
- Watch Mode: With
--watch, runs continuously checking for new tasks - Tmux Integration: Spawns agents in a reusable
ottotmux session - Graceful Shutdown: Handles Ctrl+C cleanly, waiting for agents to finish
- Beads Integration: Works with the beads issue tracking system
- Workspace Isolation: Spawns agents in isolated git worktrees for better separation and cleanup
Before using Otto, ensure you have the following installed:
-
tmux - Terminal multiplexer for session management
- NixOS:
tmuxis in nixpkgs - Ubuntu/Debian:
sudo apt install tmux - macOS:
brew install tmux
- NixOS:
-
Claude Code CLI - The AI coding agent
- Install from: https://github.com/anthropics/claude-code
-
beads (bd) - Git-based issue tracking system
- Install from: https://github.com/heartsucker/bd
- Initialize in your project:
bd init
cargo install ottonix develop
cargo install --path .git clone <repository-url>
cd otto
cargo build --releaseThe binary will be available at target/release/otto.
Run Otto in a project with beads initialized:
ottoOtto will:
- Check for ready beads (tasks with no blockers)
- Launch a Claude Code agent in a tmux session named
otto - Wait for the agent to complete
- Repeat until no ready beads remain
- Exit
For continuous operation, use the --watch (or -w) flag:
otto --watchIn watch mode, Otto will:
- Loop indefinitely
- When no ready beads exist, wait 10 seconds and check again
- Continue until you stop it with Ctrl+C
To watch the agent work, attach to the tmux session:
tmux attach-session -t ottoTo detach without stopping Otto:
- Press
Ctrl+B, thenD(the default tmux detach keybinding)
You can spawn an agent to work on a specific issue:
# Spawn agent with default workspace (recommended)
otto spawn -i otto-123
# Spawn agent in main repository (no workspace)
otto spawn -i otto-123 --no-workspace
# Spawn agent with custom workspace path
otto spawn -i otto-123 --workspace ../agents/my-featureWorkspace Isolation (enabled by default):
- Creates a git worktree at
../agents/otto-<issue-id>for isolated work - Each workspace gets a unique branch:
agent/otto-<issue-id>-<hash> - Prevents cross-contamination between different agent work
- Easy cleanup with
git worktree removeorotto done --nuke
Use --no-workspace when:
- Working on quick tasks or debugging
- You want to see changes in the main repository immediately
- Workspace isolation isn't necessary for the task
Otto runs a simple loop:
while true:
1. Check for ready beads (via `bd ready`)
2. If ready beads exist:
a. Launch Claude Code agent in tmux session
b. Agent receives fixed prompt: "Run bd ready, choose a bead, begin work on only that bead. Exit when done."
c. Wait for agent to complete (default: 5 minute timeout)
d. Repeat
3. If no ready beads:
a. Normal mode: Exit
b. Watch mode: Wait 10 seconds, then check again
All Claude Code agents launched by Otto receive the same fixed prompt:
Run bd ready, choose a bead, begin work on only that bead. Exit when done.
This prompt instructs the agent to:
- Check for available tasks
- Select one task
- Work only on that task (not multiple tasks)
- Exit when complete
This design ensures each agent focuses on a single task, maintaining clear boundaries between iterations.
Otto requires beads to be initialized in your project directory.
bd initInstall tmux using your system package manager:
- NixOS: Already available in nixpkgs
- Ubuntu/Debian:
sudo apt install tmux - macOS:
brew install tmux
Install the Claude Code CLI from: https://github.com/anthropics/claude-code
This is expected behavior when all tasks are completed or blocked. To add work:
bd create --title="Your task here" --type=task --priority=2The default agent timeout is 5 minutes. If your tasks regularly take longer, you may need to adjust the timeout in the source code (currently defined as DEFAULT_AGENT_TIMEOUT_SECS in otto-core).
When running Otto in a new directory, Claude Code may prompt:
Do you trust the files in this folder?
This is a security feature and requires manual intervention. Workaround: Run Otto in a directory you've previously approved as trusted.
Otto is intentionally simple:
- No state management: Each agent run is independent
- No metrics or logging: Simple console output only
- No configuration files: Behavior is fixed (except for
--watchflag) - No plugin system: Only Claude Code is supported
- Claude Code only: No support for other AI agents currently
Contributions are welcome! Here are some ways you can contribute:
Found a bug? Have a feature request? Please file an issue in the project's issue tracker.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Rust standard naming conventions
- Run
cargo fmtbefore committing - Run
cargo clippyto catch common issues - Ensure all tests pass (
cargo test)
# Clone the repository
git clone <repository-url>
cd otto
# Enter the development shell (Nix)
nix develop
# Or install dependencies manually
cargo buildotto/
├── crates/
│ ├── otto/ # CLI interface and main loop
│ ├── otto-core/ # Agent launching logic
│ ├── otto-beads/ # Beads integration
│ └── otto-tmux/ # Tmux session management
├── flake.nix # Nix flake for development
└── Cargo.toml # Workspace configuration
cargo buildcargo testThis project uses cargo-llvm-cov for code coverage measurement:
make test-cov # Terminal output
make test-cov-html # HTML report in coverage/
make test-cov-open # Generate and open HTML reportFor Nix setup instructions and llvm-tools requirements, see RUST-Nix.md.
nix developMIT
Mike Kusold