Skip to main content

Automated Claude Code execution in isolated environments

Project description

Iterare

Automated Claude Code execution in isolated Docker containers.

iterare creates git worktrees, launches containerised Claude Code instances with autonomous permissions, and maintains safety through network firewalls and container isolation. This enables "agentic loops" where Claude Code can modify codebases without human confirmation while being restricted to whitelisted network access and mounted files.

Warning – This does not fully protect from malicious code execution or data exfiltration. It simply raises the barriers to these things happening. Use at your own risk.

Prerequisites

  • Python 3.13+
  • uv for dependency management
  • Docker
  • A Claude Code API key

Installation

# Install via pypi
pip install iterare-llm

# Create global config directories
iterare install

# Fetch Claude Code credentials (interactive Docker session)
iterare credentials

Quick Start

The easiest way to get started is to use the interactive mode. This launches a Claude Code session in a Docker container, mounts your current project directory, and allows you to drive Claude Code yourself.

# Initialize a project
cd /path/to/your/project
iterare init

# Launch in interactive mode
iterare interactive

Alternatively, you can create a prompt file and execute it. This (by default) creates a git worktree, and branches off of the current branch. It then launches Claude Code in a Docker container, mounts the worktree directory, and passes the prompt to Claude Code which will then execute the prompt until it's done. This is fantastic for autonomous development.

# Initialize a project
cd /path/to/your/project
iterare init

# Create a prompt
cat > .iterare/prompts/refactor.md << 'EOF'
---
workspace: refactor-auth
branch: main
---

Refactor the authentication module to use JWT tokens.
Add tests for the new implementation.
EOF

# Execute the prompt
iterare execute refactor

# Monitor progress
iterare log -f

# When done, merge changes back
iterare merge

# Clean up the worktree
iterare cleanup -y

Commands

iterare init [PATH]

Initialise a project for iterare. Creates the .iterare/ directory with configuration files and a workspaces/ directory for git worktrees.

iterare init                    # Initialize current directory
iterare init /path/to/project   # Initialize specific directory
iterare init --force            # Overwrite existing configuration

iterare install

Create global configuration directories for credentials and logs.

iterare install

iterare credentials

Fetch Claude Code credentials via an interactive Docker session. Launches a container where you can log in, then extracts the credential files.

iterare credentials             # First-time setup
iterare credentials --force     # Re-authenticate
iterare credentials --image my-image:latest  # Use custom image

iterare execute <prompt>

Execute a prompt in an isolated Docker container. Creates a git worktree, mounts it in a container, and launches Claude Code in autonomous mode.

# By prompt name (looks in .iterare/prompts/)
iterare execute refactor

# By file path
iterare execute .iterare/prompts/task.md

# Reuse an existing workspace
iterare execute refactor --reuse refactor-abc12345

# Pass environment variables to the container
iterare execute refactor --env PIP_INDEX_URL --env GITHUB_TOKEN

iterare interactive

Launch an interactive Claude Code session in a container. By default runs in the project directory without creating a worktree.

# Default: run in project directory
iterare interactive

# Create a worktree for isolation
iterare interactive --worktree

# Name the workspace
iterare interactive --worktree --workspace my-feature

# Base on a specific branch
iterare interactive --worktree --branch main

# Reuse an existing workspace
iterare interactive --worktree --reuse my-feature-abc12345

# Pass environment variables
iterare interactive --env PIP_INDEX_URL

iterare log [RUN_NAME]

View execution logs for a run.

iterare log                     # Most recent run
iterare log refactor-abc12345   # Specific run
iterare log -f                  # Follow live output
iterare log --raw               # Raw JSON output
iterare log -v 0                # Minimal (text responses only)
iterare log -v 2                # Verbose (all details)

iterare list

List execution runs for the project.

iterare list                    # Active and finished runs
iterare list --all              # Include cleaned up runs

iterare merge [RUN_NAME]

Merge a worktree branch back into the current branch.

iterare merge                   # Merge most recent run
iterare merge refactor-abc12345 # Merge specific run

iterare cleanup [RUN_NAME]

Remove the git worktree and branch for a run. Log files are preserved.

iterare cleanup                 # Clean up most recent run
iterare cleanup -y              # Skip confirmation
iterare cleanup refactor-abc12345 -y  # Specific run

Configuration

Project Structure

After running iterare init, your project will contain:

.iterare/
├── config.toml               # Main configuration
├── Dockerfile                # Custom Docker image (optional)
└── prompts/                  # Prompt files
    └── example-prompt.md

workspaces/                   # Git worktrees (gitignored)

Config File (.iterare/config.toml)

[docker]
image = "iterare-llm:latest"

[session]
shell = "/bin/bash"

[claude]
credentials_path = "~/.config/iterare"

[firewall]
# Additional domains to allow through the firewall.
# Default domains (Anthropic API, GitHub, npm) are always included.
allowed_domains = [
    "pypi.org",
    "files.pythonhosted.org",
]

Prompt Files

Prompts are markdown files with optional YAML frontmatter:

---
workspace: my-feature
branch: main
---

# Task Description

Implement feature X by doing Y and Z.

Frontmatter fields:

  • workspace -- Worktree directory name (defaults to prompt filename)
  • branch -- Base branch for the worktree (defaults to current branch)

Environment Variables

Pass host environment variables to the container with --env:

export PIP_INDEX_URL="https://pypi.company.internal/simple"
iterare execute install-deps --env PIP_INDEX_URL

The flag accepts the variable name and reads the value from your shell. If a variable is not set, execution fails with an error.

Network Security

The container runs behind a whitelist-based firewall using iptables:

  • All outbound traffic is blocked by default
  • Only whitelisted domains are allowed (resolved to IPs via DNS)
  • Default whitelist includes api.anthropic.com, GitHub APIs, npm registry
  • Additional domains are configured in config.toml

This prevents the autonomous agent from exfiltrating code or downloading malicious packages from unapproved sources.

Execution Flow

  1. Load configuration from .iterare/config.toml
  2. Parse prompt file (extract frontmatter metadata)
  3. Create git worktree on a new branch
  4. Write .claude-auto-config.json and .claude-prompt.md to worktree
  5. Launch Docker container with worktree mounted at /workspace
  6. Container initializes firewall, then runs Claude Code autonomously
  7. Monitor via iterare log -f
  8. Merge results with iterare merge, clean up with iterare cleanup

Development

make sync       # Install dependencies
make test       # Run tests (289 tests)
make coverage   # Run tests with coverage report (100% coverage)
make lint       # Check code style
make format     # Auto-format code

Troubleshooting

Docker image not found

Build the images first:

make build-base
make build

Container already running

docker stop it-<run-name>
docker rm it-<run-name>

Credentials not found

Run the credentials command to authenticate:

iterare credentials

Network blocked in container

Add the required domain to your config.toml:

[firewall]
allowed_domains = ["example.com"]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iterare_llm-0.1.2.tar.gz (32.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iterare_llm-0.1.2-py3-none-any.whl (45.3 kB view details)

Uploaded Python 3

File details

Details for the file iterare_llm-0.1.2.tar.gz.

File metadata

  • Download URL: iterare_llm-0.1.2.tar.gz
  • Upload date:
  • Size: 32.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for iterare_llm-0.1.2.tar.gz
Algorithm Hash digest
SHA256 7997a6e8f37862b6aa33a1bc2044c251e5f89ad23ae639c4c12ff2c4d0ed29f3
MD5 60eea923c82ea785bcd874a956ff502a
BLAKE2b-256 c72b62fd71fe33482512a5d33973e5b88bcd8b7b7bbe0e1f64eff217ed5116fb

See more details on using hashes here.

File details

Details for the file iterare_llm-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: iterare_llm-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 45.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for iterare_llm-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7d066cdac8690a1150a10bbc703711c2c8157774afbeed0250bea8d5391ea5b9
MD5 328f84a3279048724cdbc530316095d1
BLAKE2b-256 f78a5179809d89adbae12f7249d39a7241d5621202a3f6401c96247e3fb7c493

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page