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.3.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.3-py3-none-any.whl (45.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: iterare_llm-0.1.3.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.3.tar.gz
Algorithm Hash digest
SHA256 4b9724dcd3e82764e4cd153aa92ef13399676fc30e00208605bb9c7d9d8f9a07
MD5 a12799bb3c128e702db590feeb447253
BLAKE2b-256 155d0da372c434d93feedfed21926a4f98d68b9e8497df6335644ede92ba6778

See more details on using hashes here.

File details

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

File metadata

  • Download URL: iterare_llm-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 45.2 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8949bf6054183dcc9f7bf78f0306b6d192e980891615fd0aadfbc0f9396af899
MD5 cdd39fa36f484fcc6277e906387152e2
BLAKE2b-256 a43ada30a249e3530ddc5b5457a7190b266898b3d5b333cd723b7306db074a18

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