## Stack - **Language:** Python 3.11+ - **Package manager:** [uv](https://docs.astral.sh/uv/) - **Build:** hatchling (src layout: `src/sandboxer/`) - **CLI:** typer (`sandboxer` entry point) - **Test:** pytest - **Lint / format:** ruff ## Dev Commands Run from the repo root. First-time setup: ```bash make setup # uv sync --all-groups → .venv make install # sandboxer → ~/.local/bin (ensure ~/.local/bin is on PATH) ``` Without global install, prefix commands with `uv run` from the repo root: ```bash uv run sandboxer create --profile profile.compose-e2e --input repo=/path/to/repo ``` Day-to-day verification (run before committing): ```bash make check # lint + test make test # pytest make lint # ruff check make format # ruff format (apply fixes) make build # uv build (wheel + sdist) make cli-version # smoke test: sandboxer version ``` Sandbox CLI (v0): ```bash sandboxer create # canary self-deploy (profile.sandbox-canary) sandboxer create --profile profile.compose-e2e --input repo=/path/to/repo sandboxer create --profile profile.vm-haskell-build --input vm=haskell-build --input repo=/path sandboxer create --profile profile.saas-stub # metered SaaS stub sandboxer credits show / credits add 10.00 sandboxer get sandboxer list sandboxer destroy sandboxer recreate sandboxer inspect host sandboxer inspect stale sandboxer reap-stale # dry-run; add --apply to remove export SANDBOXER_COMPOSE_CMD=podman-compose # required on CoulombCore ``` Equivalent `uv` invocations without Make: ```bash uv sync --all-groups uv run pytest uv run ruff check . uv run ruff format . uv build uv run sandboxer version ``` No long-running service yet — API and provisioner land in SAND-WP-0002.