claw-spawn 0.1.0

Digital Ocean VPS provisioning and OpenClaw bot orchestration
Documentation
# Claw Spawn - Makefile for local development
# Usage: make (builds and starts everything)
#        make help (shows all available commands)

.PHONY: all help setup check-deps db setup-env migrate build run test clean docker-build docker-run

# Default target - runs everything needed to start
all: check-deps setup-env db migrate build run

# Show all available commands
help:
	@echo "Claw Spawn - Available Commands"
	@echo "========================================"
	@echo ""
	@echo "  make          - Full setup and start (default)"
	@echo "  make setup    - Initial environment setup"
	@echo "  make db       - Create database if not exists"
	@echo "  make migrate  - Run database migrations"
	@echo "  make build    - Build release binary"
	@echo "  make run      - Start the server"
	@echo "  make dev      - Quick dev mode (checks, migrates, runs)"
	@echo "  make test     - Run all tests"
	@echo "  make clean    - Clean build artifacts"
	@echo "  make docker-build - Build Docker image"
	@echo "  make docker-run   - Run with Docker Compose"
	@echo ""
	@echo "Environment Variables Required:"
	@echo "  CLAW_DATABASE_URL      - PostgreSQL connection string"
	@echo "  CLAW_DIGITALOCEAN_TOKEN  - DigitalOcean API token"
	@echo "  CLAW_ENCRYPTION_KEY      - 32-byte base64 encoded key"
	@echo ""

# Check all required dependencies
check-deps:
	@echo "๐Ÿ” Checking dependencies..."
	@which cargo > /dev/null || (echo "โŒ Rust/Cargo not found. Install from https://rustup.rs/" && exit 1)
	@echo "โœ… Cargo found"
	@which psql > /dev/null || (echo "โŒ PostgreSQL client (psql) not found" && exit 1)
	@echo "โœ… PostgreSQL client found"
	@cargo sqlx --version > /dev/null 2>&1 || (echo "โš ๏ธ  sqlx-cli not found. Run: cargo install sqlx-cli" && exit 1)
	@echo "โœ… sqlx-cli found"
	@echo "โœ… All dependencies satisfied!"
	@echo ""

# Initial setup - create .env file if it doesn't exist
setup: check-deps setup-env
	@echo "โœ… Setup complete!"
	@echo ""
	@echo "Next steps:"
	@echo "  1. Edit .env with your actual credentials"
	@echo "  2. Run: make db"
	@echo "  3. Run: make migrate"
	@echo "  4. Run: make run"

# Create .env file from example if it doesn't exist
setup-env:
	@if [ ! -f .env ]; then \
		echo "๐Ÿ“ Creating .env file..."; \
		echo "CLAW_DATABASE_URL=postgres://postgres:postgres@localhost:5432/claw_spawn" > .env; \
		echo "CLAW_DIGITALOCEAN_TOKEN=your_digitalocean_api_token_here" >> .env; \
		echo "CLAW_ENCRYPTION_KEY=$$(openssl rand -base64 32)" >> .env; \
		echo "CLAW_SERVER_HOST=0.0.0.0" >> .env; \
		echo "CLAW_SERVER_PORT=8080" >> .env; \
		echo "CLAW_OPENCLAW_IMAGE=ubuntu-22-04-x64" >> .env; \
		echo "โœ… Created .env with default values"; \
		echo "โš ๏ธ  IMPORTANT: Edit .env and add your DigitalOcean token!"; \
	else \
		echo "โœ… .env file already exists"; \
	fi

# Create database if it doesn't exist
db:
	@echo "๐Ÿ—„๏ธ  Setting up database..."
	@if [ -z "$$CLAW_DATABASE_URL" ]; then \
		echo "โŒ CLAW_DATABASE_URL not set. Run: make setup-env"; \
		exit 1; \
	fi
	@DB_NAME=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*\/\([^?]*\).*/\1/p'); \
	DB_HOST=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*@\([^:]*\):.*/\1/p'); \
	DB_USER=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p'); \
	psql -h $$DB_HOST -U $$DB_USER -d postgres -tc "SELECT 1 FROM pg_database WHERE datname = '$$DB_NAME'" | grep -q 1 || \
		psql -h $$DB_HOST -U $$DB_USER -d postgres -c "CREATE DATABASE $$DB_NAME;" && \
		echo "โœ… Database created: $$DB_NAME" || \
		echo "โœ… Database already exists: $$DB_NAME"

# Run database migrations
migrate:
	@echo "๐Ÿ”„ Running migrations..."
	@if [ -z "$$CLAW_DATABASE_URL" ]; then \
		echo "โŒ CLAW_DATABASE_URL not set. Loading from .env..."; \
		export $$(grep -v '^#' .env | xargs) && cargo sqlx migrate run; \
	else \
		cargo sqlx migrate run; \
	fi
	@echo "โœ… Migrations complete!"

# Build release binary
build:
	@echo "๐Ÿ”จ Building release binary..."
	@cargo build --release --bin claw-spawn-server
	@echo "โœ… Build complete!"
	@echo "   Binary: target/release/claw-spawn-server"
	@echo ""

# Quick build for development
dev-build:
	@echo "๐Ÿ”จ Building (dev mode)..."
	@cargo build --bin claw-spawn-server

# Start the server
run:
	@echo "๐Ÿš€ Starting server..."
	@if [ -z "$$CLAW_DATABASE_URL" ]; then \
		echo "๐Ÿ“‹ Loading environment from .env..."; \
		export $$(grep -v '^#' .env | xargs) && ./target/release/claw-spawn-server; \
	else \
		./target/release/claw-spawn-server; \
	fi

# Quick dev mode - compile and run with hot reload on file changes
dev: check-deps dev-build
	@echo "๐Ÿš€ Starting server in dev mode..."
	@echo "   (Use Ctrl+C to stop)"
	@echo ""
	@if [ -z "$$CLAW_DATABASE_URL" ]; then \
		export $$(grep -v '^#' .env | xargs) && cargo run --bin claw-spawn-server; \
	else \
		cargo run --bin claw-spawn-server; \
	fi


# Run all tests
test:
	@echo "๐Ÿงช Running tests..."
	@cargo test
	@echo "โœ… Tests complete!"

# Check code without building
check:
	@echo "๐Ÿ” Checking code..."
	@cargo check
	@echo "โœ… Code check passed!"

# Format code
fmt:
	@echo "โœจ Formatting code..."
	@cargo fmt
	@echo "โœ… Code formatted!"

# Run linter
lint:
	@echo "๐Ÿ” Running clippy..."
	@cargo clippy -- -D warnings
	@echo "โœ… Linting complete!"

# Clean build artifacts
clean:
	@echo "๐Ÿงน Cleaning build artifacts..."
	@cargo clean
	@rm -rf target/
	@echo "โœ… Clean complete!"

# Reset everything (database, builds)
reset: clean
	@echo "โš ๏ธ  This will delete the database and all data!"
	@read -p "Are you sure? [y/N] " confirm && [ $$confirm = "y" ] || exit 1
	@if [ -z "$$CLAW_DATABASE_URL" ]; then export $$(grep -v '^#' .env | xargs); fi; \
	DB_NAME=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*\/\([^?]*\).*/\1/p'); \
	DB_HOST=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*@\([^:]*\):.*/\1/p'); \
	DB_USER=$$(echo "$$CLAW_DATABASE_URL" | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p'); \
	psql -h $$DB_HOST -U $$DB_USER -d postgres -c "DROP DATABASE IF EXISTS $$DB_NAME;" && \
	echo "โœ… Database dropped"

# Build Docker image
docker-build:
	@echo "๐Ÿณ Building Docker image..."
	@docker build -t claw-spawn:latest .
	@echo "โœ… Docker image built: claw-spawn:latest"

# Run with Docker Compose
docker-run:
	@echo "๐Ÿณ Starting with Docker Compose..."
	@if [ -f docker-compose.yml ]; then \
		docker-compose up --build; \
	else \
		echo "โŒ docker-compose.yml not found"; \
		echo "Create one or use: make run"; \
	fi

# Install sqlx-cli if not present
install-sqlx:
	@echo "๐Ÿ“ฆ Installing sqlx-cli..."
	@cargo install sqlx-cli --no-default-features --features native-tls,postgres
	@echo "โœ… sqlx-cli installed!"

# Create a new database migration
migrate-add:
	@read -p "Migration name: " name; \
	cargo sqlx migrate add $$name

# Show database status
migrate-status:
	@cargo sqlx migrate info

# Revert last migration
migrate-revert:
	@cargo sqlx migrate revert

# Quick health check
check-server:
	@echo "๐Ÿฅ Checking server health..."
	@curl -s http://localhost:8080/health && echo "" || echo "โŒ Server not running"

# Generate a new encryption key
generate-key:
	@echo "๐Ÿ”‘ New encryption key:"
	@openssl rand -base64 32
	@echo ""
	@echo "Add this to your .env file as CLAW_ENCRYPTION_KEY"

# Show current environment
env:
	@echo "๐Ÿ“‹ Current Environment:"
	@echo "======================"
	@echo "CLAW_DATABASE_URL:      $${CLAW_DATABASE_URL:-<not set>}"
	@echo "CLAW_SERVER_HOST:       $${CLAW_SERVER_HOST:-<not set>}"
	@echo "CLAW_SERVER_PORT:       $${CLAW_SERVER_PORT:-<not set>}"
	@echo "CLAW_OPENCLAW_IMAGE:    $${CLAW_OPENCLAW_IMAGE:-<not set>}"
	@echo "CLAW_DIGITALOCEAN_TOKEN: $${CLAW_DIGITALOCEAN_TOKEN:+<set>}"
	@echo "CLAW_ENCRYPTION_KEY:     $${CLAW_ENCRYPTION_KEY:+<set>}"