Contributing to Wealthbox CLI¶
Thank you for your interest in contributing to wealthbox-cli!
Development Setup¶
This project uses uv for dependency management. Install it first if you don't have it:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
Then clone and sync:
uv sync creates a project-local .venv/ and installs the package in editable mode with dev dependencies. There is nothing to "activate" — prefix commands with uv run:
Configure your Wealthbox API token (optional — tests don't require a real token):
Prefer plain
pip?pip install -e ".[dev]"still works —pyproject.tomlis the source of truth for both tools.
Pre-commit hooks¶
The repo ships a .pre-commit-config.yaml with three hooks: ruff lint, mypy strict, and a skill-ref drift check. Install them once after cloning:
# uv
uv tool install pre-commit
pre-commit install
# or pip
pip install pre-commit
pre-commit install
Run all hooks manually at any time:
Running Tests¶
Tests use respx to mock HTTP at the transport layer — no real API calls are made.
Coverage gate¶
CI enforces --cov-fail-under=91 on the ubuntu test leg. Run locally with:
Code Style¶
- ruff for linting (E, F, I rules; 120-char line length)
- mypy in strict mode (
uv run mypy src/must exit 0)
Project Architecture¶
Three layers under src/wealthbox_tools/:
| Layer | Purpose |
|---|---|
cli/ |
Typer commands — user-facing, delegates to client |
client/ |
Async HTTP client built from httpx mixins |
models/ |
Pydantic v2 models for input validation |
WealthboxClient (in client/__init__.py) inherits from all resource mixins plus _WealthboxBase (core HTTP, rate limiting, error handling).
Adding a New Resource¶
- Add Pydantic models to
models/<resource>.py(CreateInput, UpdateInput, ListQuery) - Add a client mixin to
client/<resource>.pywith async CRUD methods - Register the mixin in
client/__init__.py - Add CLI commands to
cli/<resource>.py - Register the CLI sub-app in
cli/main.py - Add category types via
make_category_command()if applicable - Add tests in
tests/test_<resource>_create.pyandtests/test_<resource>_update.py
Skill reference files¶
Any change to CLI command signatures or help text must regenerate the skill reference files before committing:
The generated files live under src/wealthbox_tools/skills/wealthbox-crm/references/ and are checked in. The skill-ref-drift CI job and the pre-commit hook both fail on stale refs.
Standing verification¶
Run all of these before opening a PR (CI enforces each):
uv run ruff check src/ tests/
uv run pytest
uv run mypy src/
uv run wbox internals regen-skill-refs && git diff --exit-code -- src/wealthbox_tools/skills/wealthbox-crm/references/
Releasing¶
Releases follow semantic versioning. Bump patch for fixes, minor for features, major for breaking changes.
- Bump
versioninpyproject.toml. - Add a
## [X.Y.Z]entry at the top ofCHANGELOG.md(CI enforces that the changelog version matchespyproject.tomlbefore publishing to PyPI). - Verify locally:
uv run ruff check src/ tests/ && uv run pytest && uv run mypy src/ - Commit:
vX.Y.Z: <description> - Tag:
git tag vX.Y.Z - Push:
git push origin main --tags
CI builds and publishes to PyPI automatically on v* tags once lint, tests, typecheck, and skill-ref-drift all pass.
CI¶
Pull requests and pushes to main run GitHub Actions CI:
- Lint:
ruff check src/ tests/ - Test:
pytestacross Python 3.11, 3.12, 3.13 (ubuntu) + 3.12 (windows); coverage gate--cov-fail-under=91on ubuntu - Typecheck:
mypy src/(strict) - Smoke: installs the built wheel in isolation (no dev deps) and runs
wbox --version/wbox notes --help, catching missing-runtime-dependency startup crashes - Skill-ref drift: regenerates refs and asserts no git diff
All jobs must pass before merging; publish (on v* tags) additionally gates on lint, test, typecheck, and smoke.
Pull Requests¶
- Keep PRs focused — one feature or fix per PR
- All tests must pass
- No ruff errors
- Update the CLI reference docs if commands change
Reporting Issues¶
Open an issue at github.com/massive-value/wealthbox-cli/issues with steps to reproduce, expected behavior, and actual behavior.