export VIRTUAL_ENV := "" # Use sudo for docker if the current user isn't in the docker group docker := if `docker info > /dev/null 2>&1 && echo ok || echo fail` == "ok" { "docker" } else { "sudo docker" } # Install project + dev dependencies install-dev: uv sync # Format + lint + type check check: format-check lint typecheck # Strict checks: unused imports, args, complexity check-strict: uv run --inexact ruff check --select F401,F841,ARG,PLR0913,C901,RUF src/ test/ # Auto-format + auto-fix lint fix: uv run --inexact ruff format src/ test/ uv run --inexact ruff check --fix src/ test/ # Format source format: uv run --inexact ruff format src/ test/ # Check formatting without modifying format-check: uv run --inexact ruff format --check src/ test/ # Lint source lint: uv run --inexact ruff check src/ test/ # Type check typecheck: uv run --inexact mypy src/ # Run tests test: uv run --inexact pytest # Build sdist + wheel build: uv build # Remove caches + dist clean: rm -rf dist/ .mypy_cache/ .ruff_cache/ .pytest_cache/ find . -type d -name __pycache__ -exec rm -rf {} + # --- Docker --- # Build the claude-py test image docker-build: {{docker}} compose -f compose/scenarios/test.yml build claude-py # Run dockerized integration test (standalone, no proxy) docker-test mode="chat": {{docker}} compose -f compose/scenarios/test.yml build claude-py {{docker}} compose -f compose/scenarios/test.yml run --rm -e TEST_MODE={{mode}} claude-py # Run dockerized test with mitmproxy traffic capture docker-capture mode="chat": {{docker}} compose -f compose/scenarios/capture.yml build claude-py {{docker}} compose -f compose/scenarios/capture.yml run --rm -e TEST_MODE={{mode}} claude-py # Tear down all docker test resources docker-down: -{{docker}} compose -f compose/scenarios/test.yml down -{{docker}} compose -f compose/scenarios/capture.yml down -v