Thanks for your interest in contributing to Runtm – sandboxes where coding agents build and deploy.
runtm.com | app.runtm.com | Discord
These principles guide all decisions. Keep them in mind when contributing:
- Simplify to the most basic primitives - Remove complexity, not add it
- Make it extremely easy to use - One command should do the job
- Make it versatile and scalable - Entire ecosystems can be built on top
- Optimize for tight, closed feedback loops - Fast iteration over perfect planning
- Design for agents first, then for humans - AI should be the primary user
- Agents propose, humans set guardrails - Freedom with governance
- Make behavior explicit, observable, and reproducible - No magic
If you're using an AI assistant to contribute, the .cursor/rules/ directory contains comprehensive context:
| File | Purpose |
|---|---|
.cursor/rules/system-instructions.mdc |
Architecture, types, CLI commands, API endpoints |
.cursor/rules/templates.mdc |
Template creation and maintenance guidelines |
These files are automatically loaded by Cursor and provide essential context for AI-assisted development. You can replicate them to fit with Claude Code: CLAUDE.md.
- Python 3.9+
- Docker & Docker Compose
- Git
- Fly.io account + API token (for deployment testing)
-
Fork the repository
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/runtm.git cd runtm -
Copy environment template and configure:
cp infra/local.env.example .env # Edit .env and add your FLY_API_TOKEN -
Install packages using the dev script:
./scripts/dev.sh setup
Or manually with uv (recommended):
uv pip install -e packages/shared[dev] uv pip install -e packages/api[dev] uv pip install -e packages/worker[dev] uv pip install -e "packages/cli[dev,sandbox]" uv pip install -e packages/sandbox uv pip install -e packages/agentsOr with pip:
pip install -e packages/shared[dev] pip install -e packages/api[dev] pip install -e packages/worker[dev] pip install -e "packages/cli[dev,sandbox]" pip install -e packages/sandbox pip install -e packages/agents -
Set up pre-commit hooks:
pip install pre-commit pre-commit install
After running ./scripts/dev.sh setup, use runtm-dev for development:
# Activate venv (or add .venv/bin to PATH)
source .venv/bin/activate
# Use the development CLI
runtm-dev start # Start a sandbox session
runtm-dev prompt "Build an API" # Send prompt to agent
runtm-dev list # List sessionsWhy two CLIs?
| CLI | Source | Includes |
|---|---|---|
runtm |
PyPI (pip install runtm) |
Core CLI only |
runtm-dev |
Local .venv/ |
CLI + sandbox + agents + all deps |
The setup script installs everything (Python packages, Bun, sandbox-runtime, Claude CLI), so runtm-dev start just works.
Start the full local stack (API, worker, database, Redis):
./scripts/dev.sh upConfigure CLI to use local API:
export RUNTM_API_URL=http://localhost:8000
export RUNTM_API_KEY=dev-token-change-in-productionThe ./scripts/dev.sh helper automatically loads your .env file:
| Command | Description |
|---|---|
./scripts/dev.sh setup |
Install all packages in dev mode |
./scripts/dev.sh up |
Start local services (auto-loads .env) |
./scripts/dev.sh down |
Stop local services |
./scripts/dev.sh restart |
Restart services (auto-loads .env) |
./scripts/dev.sh rebuild |
Rebuild images and restart (after code changes) |
./scripts/dev.sh logs [service] |
View logs (e.g., logs worker) |
./scripts/dev.sh test |
Run tests |
./scripts/dev.sh lint |
Run linter |
./scripts/dev.sh format |
Format code |
packages/
shared/ # Canonical contracts: manifest schema, types, errors
sandbox/ # Local sandbox runtime (OS-level isolation)
agents/ # AI coding agent adapters (Claude Code, Codex, etc.)
api/ # FastAPI control plane
worker/ # Build + deploy worker (Fly.io provider)
cli/ # Python CLI (Typer)
templates/
backend-service/ # Python FastAPI backend (API, webhooks, agents)
static-site/ # Next.js static site (landing pages, docs)
web-app/ # Fullstack Next.js + FastAPI (dashboards, apps)
infra/
docker-compose.yml # Local development stack
| Package | Purpose | Key Principle |
|---|---|---|
shared |
Canonical contracts only | Types/schemas/errors that other packages import |
sandbox |
Local sandbox runtime | OS-level isolation for AI agents |
agents |
AI agent adapters | Wraps Claude Code, Codex, etc. |
api |
HTTP layer + orchestration | No business logic in routes - use services |
worker |
Build/deploy pipeline | Provider abstraction for Fly.io/Cloud Run |
cli |
User interface | Wraps API client, never contains business logic |
We use Ruff for linting and formatting:
# Check for issues
./scripts/dev.sh lint
# or: ruff check .
# Auto-fix issues
ruff check --fix .
# Format code
./scripts/dev.sh format
# or: ruff format .- Structured logging everywhere, no print statements
- Clean error messages that explain how to recover
- Idempotency: retries create same result
- Type hints on all functions
- Real tests for critical paths
Run tests with pytest:
# All tests via dev script
./scripts/dev.sh test
# All tests directly
pytest
# Specific package
pytest packages/api/tests
pytest packages/shared/tests
pytest packages/cli/tests
# With coverage
pytest --cov=runtm_api packages/api/tests| File | Purpose |
|---|---|
packages/shared/runtm_shared/manifest.py |
Deployment manifest schema (Pydantic) |
packages/shared/runtm_shared/types.py |
State machine, tiers, auth types |
packages/shared/runtm_shared/errors.py |
Error hierarchy |
packages/api/runtm_api/routes/deployments.py |
Deployment API endpoints |
packages/worker/runtm_worker/jobs/deploy.py |
Build/deploy job logic |
packages/worker/runtm_worker/providers/fly.py |
Fly.io provider implementation |
packages/cli/runtm_cli/main.py |
CLI command definitions |
- Create command function in
packages/cli/runtm_cli/commands/ - Export from
packages/cli/runtm_cli/commands/__init__.py - Register in
packages/cli/runtm_cli/main.py - Add tests in
packages/cli/tests/
- Add route in
packages/api/runtm_api/routes/ - Keep route handlers thin – delegate to services
- Use Pydantic models for request/response
- Add tests in
packages/api/tests/
- Create provider in
packages/worker/runtm_worker/providers/ - Implement the
DeploymentProviderinterface - Register in provider factory
- Edit in
packages/shared/runtm_shared/ - Update all consuming packages
- Types flow: shared → api, worker, cli
See .cursor/rules/templates.mdc for comprehensive template guidelines.
-
Create a feature branch from
main:git checkout -b feature/my-feature
-
Make your changes and ensure:
- Tests pass:
./scripts/dev.sh test - Linting passes:
./scripts/dev.sh lint - Code is formatted:
./scripts/dev.sh format
- Tests pass:
-
Commit with a clear message:
git commit -m "feat: add new deployment status endpoint" -
Push and open a Pull Request
We follow Conventional Commits:
feat:New featurefix:Bug fixdocs:Documentation changeschore:Maintenance tasksrefactor:Code refactoringtest:Test additions/changes
Open a GitHub issue or join our Discord for questions about contributing.