Contributing
sportsclaw is developed in the open by the Machina Sports team and outside contributors. Bug fixes, new bot surfaces, benchmark cases and docs all land through pull requests on GitHub — the same way the core team ships.
- commits
- 574
- merged PRs
- 186
- contributors
- 5
- latest release
- v0.29.4
- first commit
- Feb 2026
Where your change belongs
| You want to… | Go to |
|---|---|
| Fix or extend the engine, bots, relay or CLI | machina-sports/sportsclaw |
| Add a sport, league or data endpoint | machina-sports/sports-skills — sportsclaw discovers installed skills on its own |
| Improve these docs | this repository, under docs/ |
| Report a bug or propose a feature | GitHub issues |
| Talk it through first | the Machina Sports Discord |
Set up
git clone https://github.com/machina-sports/sportsclaw
cd sportsclaw
npm install # npm only: no pnpm or bun in this repo
npm run build # tsc, strict
npm test # build, then the node:test suiteTo run real queries locally you also need the data layer and a model key:
pip install sports-skills
export ANTHROPIC_API_KEY=sk-... # or OPENAI_API_KEY / GEMINI_API_KEY / AZURE_FOUNDRY_API_KEY
node dist/index.js "What are today's NBA scores?"node dist/index.js doctor tells you what's missing.
Conventions
- Stack: Node.js, TypeScript, ESM. Use npm.
- Names: files in kebab-case (
game-alerts.ts), functions and variables in camelCase, types and classes in PascalCase. - Imports: local imports use explicit
.jsextensions — ESM requires it. - Async:
async/awaitover promise chains; wrap the specific call that can fail intry/catch. - No invented feeds: never assume a sport, league or endpoint exists until it's in sports-skills. If the data layer can't fetch it, the agent can't claim it.
- Tests:
node:testfiles intest/*.test.mjs. Most areas have a focused script, e.g.npm run test:guardrailsornpm run test:game-alerts.
What CI checks
Every pull request — whatever its base branch, so stacked PRs work — runs:
- Build:
npm ciandnpm run buildwith strict TypeScript. - Tests: every
test/*.test.mjsundernode:test, with FFmpeg installed for the media contracts. - Smoke:
test/ci-smoke.mjsboots the engine with no API key at all.
Live-provider tests are not part of required CI because they need secrets. Run npm run test:ci-integration yourself when you change how a model provider is called.
Working on the docs
npm run docs:dev # local preview with hot reload
npm run docs:build # the same build the site deploy runs- Pages are Markdown in
docs/; the navigation and sidebar live indocs/.vitepress/config.mts. - The landing page and footer are Vue components in
docs/.vitepress/theme/components/. - Dead links fail the build. Link to repository files outside
docs/with a full GitHub URL, not a relative path. - Every page ends with a Suggest an edit on GitHub link — the fastest way to fix a typo.
Pull requests
- Branch from
mainand keep each PR focused on one change. - Say what changed and how you verified it: commands you ran, output you checked.
- Add or update tests next to the behavior you changed.
- If you change user-facing behavior, update the page that documents it in the same PR.
Maintainers at Machina Sports review and merge.
Releases
v*tags mark engine releases on GitHub and deploy this site.relay-v*tags build the relay image that Machina projects run.- The npm package is
sportsclaw-engine-core.
Acknowledgements
sportsclaw's execution engine draws on NanoClaw, OpenClaw, NemoClaw and pi.dev. It's built on the Vercel AI SDK for multi-provider models, and the interactive setup uses Clack.