relay

Contributing

Welcome. This page covers code style, the dev loop, tests, and how to add a provider.

Setup

One command:

./scripts/setup.sh        # macOS/Linux
./scripts/setup.ps1       # Windows

It will:

  1. Check / install Go 1.24+, Rust (stable), Node 18+ — or just run ./scripts/setup.sh (self-healing).
  2. Pull all submodules.
  3. go mod download, cargo fetch.
  4. Build both binaries to ./bin/.
  5. Run a smoke test (start daemon, GET /api/health, kill).

Manual setup is also fine — see getting-started.md.

Dev loop

./scripts/dev.sh

Runs three things in parallel with hot-reload:

Stop with Ctrl+C — kills all three cleanly.

Tests

./scripts/test.sh

CI runs the same in .github/workflows/ci.yml. Tests must pass before merge.

Code style

Go

Rust

Commits

Adding a provider

See providers.md. Five files touched:

  1. internal/adapter/interface.go — add ProviderName const.
  2. internal/adapter/yourtool.go — implement AdapterContract.
  3. internal/adapter/registry.go — register.
  4. cmd/relay/providers.go — metadata + probe arm.
  5. internal/pricing/pricing.go — pricing.

Add a unit test for your Run event parsing using a recorded fixture.

Adding a UI page

In packages/ui/src/app.rs:

  1. Add a variant to NavPage.
  2. Add an icon to paint_icon (16×16 viewBox, SVG-derived path).
  3. Add a row to IconRail / FullSidebar items.
  4. Write draw_yourpage(ui, state).
  5. Add a match arm in draw_central.

If the page needs state, mirror the existing pattern: stash via ui.ctx().data_mut(|m| m.insert_temp(id, value)). Don't add fields to RelayApp unless they need to outlive a single frame.

PR checklist

Areas welcoming contributions

Tagged on GitHub with good first issue:

Big-ticket roadmap items in docs/architecture.md.

Code of conduct

Be respectful. We follow the Contributor Covenant.

License

Contributions are licensed under Apache-2.0, the same as the project.