Local development guide for
orclaw. Server deployment is indeployment.md.
- Python 3.11+
ghCLI authenticated (for any integration test that hits GitHub)- SQLite 3 (system-provided on macOS/Linux; bundled with Python on Windows)
git clone https://github.com/jaschez/orclaw.git
cd orclaw
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"The editable install registers the orclaw CLI in your virtualenv.
The CLI works out of the box without a server. It looks for config in
./config/ (in this repo) and a SQLite DB at /var/lib/orclaw/data/engine.db
by default — override the data dir with ORCLAW_CONFIG_DIR or a
custom PathsSettings (sprint 2+ adds a --data-dir flag).
# Show version + git rev
orclaw version
# Print resolved settings (no secrets shown)
orclaw config show
# Create the DB locally for development
mkdir -p ./dev-data
ORCLAW_DATA_DIR=./dev-data orclaw db init # sprint 2 wires this env var
# Show status (empty until orchestrator writes batches/runs)
orclaw statusSprint-1 caveat: the CLI uses the production paths in
PathsSettingsunless you overrideORCLAW_CONFIG_DIRto a dir containing a custom TOML that redirects them. Sprint 2 makes this cleaner with a global--data-dir.
pytest # unit tests
pytest -m "not slow" # skip slow tests
pytest --cov=orclaw # with coverageWe target 80%+ coverage on the foundational layers (config, db, parser). Edge function specifics are covered by tests that arrive in later sprints.
ruff check . # lint
ruff format . # format (idempotent)
mypy orclaw # type-checkCI runs all three in .github/workflows/ci.yml (to be added when the
repo grows).
orclaw/
├── __init__.py # version
├── __main__.py # python -m orclaw
├── cli.py # Click entry point
├── config.py # TOML + env loader, Settings dataclass
├── db.py # SQLite connection + init_db
├── dependency_parser.py # parse "Blocked by #N"
├── exceptions.py # OrclawError hierarchy
├── github_client.py # async REST/GraphQL client
├── logging.py # structlog setup
└── models.py # frozen dataclasses: Issue, PR, Run, Batch, ...
tests/
├── conftest.py # shared fixtures
├── test_config.py
├── test_db.py
├── test_dependency_parser.py
└── test_github_client.py
Sprints 2-5 add:
orclaw/orchestrator/— long-running coordinator + looporclaw/batch_planner/— dep-graph layeringorclaw/agents/— wrappers that build and post @claude commentsorclaw/notifications/— Telegram, Slack, Healthchecksorclaw/dashboard/— FastAPI HTTP server
- Type annotations on every new function (including private).
mypy --strict. - Public symbols documented with one-line docstrings minimum. Modules get a top-of-file docstring explaining why the file exists.
- Errors raised through the
OrclawErrorhierarchy — never bareExceptionorRuntimeError. - Logging:
structlogonly. Never useprintoutside the CLI.
For end-to-end tests against the real ${TARGET_REPO} repo, set:
export GITHUB_TOKEN=ghp_...
export GITHUB_REPO=${TARGET_REPO}…then run scripts under scripts/dev/ (added in sprint 2). Be sure your
PAT has the right scopes (repo, project, workflow).
- Forgetting
from __future__ import annotationsat the top — needed forstr | Nonesyntax to type-check on 3.11. - Re-implementing logger setup inside a module — call
get_logger(__name__)and rely on the global config fromconfigure_logging(). - Catching
Exceptionbroadly — catch the domain-specific exception fromorclaw.exceptions.