Thanks for your interest in contributing. This document covers what you need to know to get a patch merged.
This project adheres to the Contributor Covenant. By participating you are expected to uphold it. Report unacceptable behaviour by opening a private discussion on the repository or messaging a maintainer directly.
- Open an issue first for anything beyond a small fix. A 5-line discussion on the issue tracker saves a 500-line PR going in the wrong direction.
- One logical change per PR. Refactors, formatting sweeps, and feature work go in separate PRs.
- No new dependencies without justification. Pinax is deliberately small; every dependency is a long-term maintenance commitment.
- Keep the scope tight. Pinax is intentionally a small local CLI. For anything beyond a bug fix or a focused improvement, open an issue first so we can confirm it fits before you spend time on a PR.
Requires Go 1.25 or newer. macOS, Linux, and WSL are supported.
git clone https://github.com/desmondsanctity/pinax.git
cd pinax
make build
make test| Command | What it does |
|---|---|
make build |
Build the pinax binary to ./bin/pinax |
make test |
Unit tests with -race, 120 s timeout |
make test-integration |
Network-touching integration tests (build tag) |
make vet |
go vet ./... |
make fmt |
gofmt -s -w . |
make tidy |
go mod tidy |
./bin/pinax add https://docs.convex.dev
./bin/pinax serve convex-docs --http --port 8423
# Open http://localhost:8423/ for the log viewer- Format with
gofmt -s. CI rejects unformatted code. - Errors are values. Wrap with
fmt.Errorf("operation: %w", err); do not swallow. - Comments are sparing. Prefer self-documenting names. Add a one-liner when intent is non-obvious; do not narrate code in block comments.
- No
panicin library code.cmd/pinaxmay exit;internal/*returns errors. - Validate at boundaries only. Don't re-validate args between internal functions; trust the type system.
- Public surface stays small. If a symbol doesn't need to be exported, don't export it.
- No global state. Pass dependencies through constructors (
tools.New,cache.Open,manifest.Store, etc.). - Tests live next to the code in
_test.gofiles, in the_testpackage where practical, to enforce the public-API contract.
Every behaviour change ships with a test. We use the standard library
testing package; no external test framework.
- Unit tests (
make test) must pass with-raceand complete in under 120 s. Usehttptest.NewServerfor HTTP behaviour; do not hit the network. - Integration tests (
make test-integration) live behind the//go:build integrationtag and may make real network calls. Keep them deterministic — pin to URLs that change slowly and assert on stable invariants (page count > N, section names contain X). - Bug fixes ship with a regression test that fails before the fix and passes after. Reference the issue in the test name when relevant.
Run a single package:
go test ./internal/mcp/tools -run TestSearchPages -count=1 -vWe use Conventional Commits:
feat(crawler): filter sitemap URLs by base path
fix(tools): tokenize natural-language queries
docs: explain the four-tool design
test(cache): cover sub-second TTLs
chore: bump golang.org/x/net to v0.31.0
Scopes match the top-level internal/* package or cmd/pinax.
Before opening a PR, make sure:
-
make fmt vet testpasses locally - New behaviour has a test; bug fixes have a regression test
- No new dependencies, or justification in the PR description
- No changes to
go.modother than what your code requires -
README.mdupdated if you changed user-visible behaviour - Commit messages follow Conventional Commits
- PR description explains the why, not just the what
Open an issue with:
- Pinax version (
pinax --version) - Go version (
go version) and OS - The exact command and the docs URL involved
- Expected vs actual behaviour
- Relevant lines from
~/.pinax/calls.db(visible in the log UI) or the server's stderr
Do not report vulnerabilities via public issues. Use GitHub Security Advisories. See SECURITY.md for the full policy.
By contributing, you agree that your contributions will be licensed under the MIT License.