Running Keystone
Keystone generates a working .devcontainer/ configuration for any git repository. It creates a devcontainer.json, Dockerfile, and run_all_tests.sh by running a coding agent inside a Modal sandbox.
Installation
# From PyPI
pip install imbue-keystone
# Or run without installing
uvx imbue-keystone --help
Both install the keystone CLI command.
Prerequisites
- Modal account — sign up here, then
modal token set $ANTHROPIC_API_KEY— set in your environment (used by the agent inside the sandbox)$DOCKER_REGISTRY_MIRROR— URL of a Docker Hub pull-through cache (e.g.https://mirror.gcr.io), required when running in Modal
Basic usage
git clone https://github.com/psf/requests
keystone \
--project_root ./requests \
--provider claude \
--model claude-opus-4-6 \
--claude_reasoning_level medium \
--max_budget_usd 1.0 \
--test_artifacts_dir /tmp/test_artifacts
CLI options
| Flag | Default | Description |
|---|---|---|
--project_root |
(required) | Path to the git repo |
--test_artifacts_dir |
(required) | Directory for JUnit XML test reports |
--provider |
claude |
LLM provider: claude, codex, or opencode |
--model |
(required) | Model identifier (see below) |
--max_budget_usd |
1.0 |
Cost cap for agent inference |
--agent_time_limit_seconds |
3600 |
Agent timeout |
--image_build_timeout_seconds |
1800 |
Docker build timeout |
--test_timeout_seconds |
1800 |
Test suite timeout |
--agent_in_modal / --run_agent_locally_with_dangerously_skip_permissions |
Modal | Run in Modal sandbox (default) or locally |
--claude_reasoning_level |
(required for claude) | low, medium, or high |
--codex_reasoning_level |
(required for codex) | low, medium, or high |
--guardrail / --no_guardrail |
enabled | Structural checks on agent output |
--use_agents_md / --no_use_agents_md |
disabled | Use AGENTS.md + short prompt instead of full inline prompt |
--log_db |
~/.imbue_keystone/log.sqlite |
SQLite or PostgreSQL URL for caching/logging |
--require_cache_hit |
false |
Fail on cache miss (for CI) |
--no_cache_replay |
false |
Skip cache, force fresh run |
--output_file |
stdout | Write JSON result to file |
--docker_registry_mirror |
$DOCKER_REGISTRY_MIRROR |
Pull-through cache URL |
--cost_poll_interval_seconds |
30 |
How often to poll cost and enforce budget (0 disables) |
Available models
| Provider | Model ID | Enum |
|---|---|---|
| claude | claude-opus-4-6 |
LLMModel.OPUS |
| claude | claude-haiku-4-5-20251001 |
LLMModel.HAIKU |
| codex | gpt-5.1-codex-mini |
LLMModel.CODEX_MINI |
| codex | gpt-5.2-codex |
LLMModel.CODEX |
| codex | gpt-5.3-codex |
LLMModel.CODEX_53 |
| codex | gpt-5.4 |
LLMModel.GPT_54 |
| opencode | anthropic/claude-opus-4-6 |
LLMModel.OPENCODE_OPUS |
| opencode | anthropic/claude-haiku-4-5 |
LLMModel.OPENCODE_HAIKU |
| opencode | openai/gpt-5.1-codex-mini |
LLMModel.OPENCODE_CODEX_MINI |
| opencode | openai/gpt-5.2-codex |
LLMModel.OPENCODE_CODEX |
| opencode | openai/gpt-5.4 |
LLMModel.OPENCODE_GPT_54 |
Output
Keystone writes a BootstrapResult JSON to stdout (or --output_file) containing:
success— whether the devcontainer was built and tests passedagent— execution details (duration, cost, tokens, status messages)verification— image build time, test execution time, pass/fail countsgenerated_files— contents of the generateddevcontainer.json,Dockerfile, andrun_all_tests.sherror_message— what went wrong (if anything)
The generated .devcontainer/ directory is also written directly into --project_root.
Examples
# Claude with high reasoning
keystone --project_root ./myrepo --provider claude --model claude-opus-4-6 \
--claude_reasoning_level high --max_budget_usd 5.0 \
--test_artifacts_dir /tmp/artifacts
# Codex
keystone --project_root ./myrepo --provider codex --model gpt-5.3-codex \
--codex_reasoning_level medium --max_budget_usd 5.0 \
--test_artifacts_dir /tmp/artifacts
# OpenCode (no reasoning level, no cost cap)
keystone --project_root ./myrepo --provider opencode \
--model anthropic/claude-opus-4-6 --max_budget_usd 0 \
--test_artifacts_dir /tmp/artifacts
# Run locally (no Modal sandbox — use with caution)
keystone --project_root ./myrepo --provider claude --model claude-opus-4-6 \
--claude_reasoning_level medium --max_budget_usd 1.0 \
--run_agent_locally_with_dangerously_skip_permissions \
--test_artifacts_dir /tmp/artifacts
# From source
uv run keystone --project_root ./myrepo --provider claude --model claude-opus-4-6 \
--claude_reasoning_level medium --max_budget_usd 1.0 \
--test_artifacts_dir /tmp/artifacts