Thank you for your interest in contributing! This document covers everything you need to get started.
git clone https://github.com/bedrock-python/clientwright.git
cd clientwright
uv sync --group dev --all-extras
uv run pre-commit install --hook-type pre-commit --hook-type commit-msgmake fmt # ruff format + ruff check --fix
make check # ruff lint + format check + mypy + import-linter contracts
make test-unit # unit tests
make test-integration # integration tests against an in-process origin server
make test # full suite with the 97% coverage thresholdNo Docker anywhere: the integration suite starts its own HTTP origin in-process.
The import-linter contracts in make check are load-bearing — they are what
keeps core/ free of adapter and SDK imports.
Tests that hit the public internet are opt-in and never run by default:
make test-live # or: uv run pytest tests/live --live- Type hints on all functions and methods, including tests
- Docstrings on public API only — Google style
- Line length — 120 characters (ruff enforced)
- Quotes — double quotes (ruff enforced)
- No comments unless the why is non-obvious
Conventional Commits are enforced by pre-commit:
| Prefix | Use for |
|---|---|
feat: |
New feature or behaviour |
fix: |
Bug fix |
docs: |
Documentation only |
test: |
Test additions or changes |
refactor: |
Code restructure, no behaviour change |
perf: |
Performance improvement |
chore: |
Build, tooling, CI |
Breaking changes: add ! after the type (feat!:) or include a BREAKING CHANGE: footer.
- Fork the repository
- Create a branch from
master:git checkout -b feat/my-feature - Make your changes with tests
- Run
make check && make test-unitlocally - Open a PR against
master
docs/agents.md is the whole library on one page, written for a coding assistant: the
public API with its real defaults, where the boundary between the core engine and an
adapter runs, the rules that break code when they are broken, the mistakes models make,
and a map of which page to fetch for the rest. People hand it to an assistant instead of
the site, which is what makes a stale one worse than none — it teaches a model an API
that no longer exists.
It is part of the public API, so it changes in the same pull request the API does: a name
added, renamed or removed, a changed default or signature, a new capability or failure
kind, a new rule a caller has to obey. A new docs page means a new row in the
documentation map. The review check is mechanical — if the diff changes the public
surface and docs/agents.md is untouched, the pull request is not finished.
Releases are fully automated via Release Please. Merge a PR with conventional commits → Release Please creates a release PR → merge it → PyPI publish happens automatically.