CONTRIBUTING.md 6.2 KB

Contributing to Dune Weaver

Thanks for your interest in contributing to Dune Weaver! Whether it's a bug fix, a new feature, or improved docs, every contribution helps make kinetic sand tables more accessible.

If you have questions or ideas, join the #dev channel on Discord or browse the existing Issues.

Development Setup

Prerequisites

  • Python 3.10+
  • Node.js 18+ and npm
  • Git

Clone and install

git clone https://github.com/tuanchris/dune-weaver.git
cd dune-weaver

# Python dependencies (use nonrpi on a dev machine, full requirements.txt on a Raspberry Pi)
pip install -r requirements-nonrpi.txt

# Testing/dev extras
pip install -r requirements-dev.txt

# Frontend + root dependencies
npm install
cd frontend && npm install && cd ..

Start the dev server

npm run dev

This runs both servers concurrently:

Service URL Notes
Frontend http://localhost:5173 Vite dev server with hot reload
Backend http://localhost:8080 FastAPI (proxied by Vite in dev)

Open http://localhost:5173 in your browser. Vite proxies all API and WebSocket requests to the backend automatically.

Project Structure

dune-weaver/
├── frontend/           # React 19 + TypeScript + Vite
│   ├── src/
│   │   ├── pages/      # Route-level page components
│   │   ├── components/ # Shared UI and feature components
│   │   ├── hooks/      # Custom React hooks
│   │   ├── lib/        # Utilities and API client
│   │   └── contexts/   # React contexts (multi-table, etc.)
│   └── package.json
├── modules/            # Backend modules
│   ├── core/           # Pattern/playlist managers, state, scheduling
│   ├── connection/     # Serial and WebSocket hardware communication
│   ├── led/            # WLED integration
│   └── mqtt/           # MQTT integration
├── patterns/           # .thr pattern files (theta-rho coordinates)
├── main.py             # FastAPI application entry point
└── package.json        # Root scripts (dev, build, prepare)

Running Tests

Backend (pytest)

pytest tests/unit/ -v
pytest tests/unit/ -v --cov       # with coverage

Frontend (Vitest)

cd frontend && npm test           # single run
cd frontend && npm run test:watch # watch mode
cd frontend && npm run test:coverage

End-to-end (Playwright)

cd frontend && npx playwright install chromium   # first time only
cd frontend && npm run test:e2e
cd frontend && npm run test:e2e:ui               # interactive UI mode

Hardware Integration Tests (pytest)

Integration tests exercise real hardware — serial connections, homing, movement, and pattern execution. They are skipped by default and in CI.

# Run all integration tests (hardware must be connected via USB)
pytest tests/integration/ --run-hardware -v

# Run a specific suite
pytest tests/integration/test_hardware.py --run-hardware -v

# Show live output (useful for watching motor activity)
pytest tests/integration/ --run-hardware -v -s
Test file What it covers Approx. duration
test_hardware.py Serial connection, homing, movement, pattern execution ~5–10 min
test_playback_controls.py Pause, resume, stop, skip, speed control ~5 min
test_playlist.py Playlist modes, clear patterns, state updates ~5 min

Safety: These tests physically move the table. Make sure the ball path is clear and the table is powered on before running them.

Linting

Python — Ruff

ruff check .                # check for issues
ruff check --fix .          # auto-fix what it can

Frontend — ESLint

cd frontend && npm run lint

Pre-commit hook

A pre-commit hook runs Ruff on staged Python files and Vitest on staged TypeScript files automatically. It's installed when you run npm install at the repo root (via the prepare script). You can also install it manually:

cp scripts/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit

Branch and Commit Conventions

Branching

Create branches from main using these prefixes:

  • feature/ — new functionality (e.g., feature/pattern-editor)
  • fix/ — bug fixes (e.g., fix/playlist-reorder)
  • chore/ — maintenance, tooling, docs (e.g., chore/update-deps)

Commit messages

We follow Conventional Commits:

feat(ui): add dark mode toggle to settings page
fix(backend): prevent crash when serial port disconnects
chore: update Python dependencies

Adding API Endpoints

When you add a new backend endpoint, you must also register its path in the Vite proxy so it works during development:

  1. Add the route in main.py (or the appropriate module).
  2. Open frontend/vite.config.ts and add the endpoint path to the server.proxy object:

    '/my_new_endpoint': 'http://localhost:8080',
    
  3. Restart the Vite dev server (npm run dev).

Tip: Endpoints under the /api prefix are already proxied by a single rule, so prefer using /api/... paths for new routes.

Submitting a Pull Request

  1. Fork the repository and clone your fork.
  2. Create a branch from main (see Branch and Commit Conventions).
  3. Make sure all tests pass and linting is clean:

    ruff check .
    cd frontend && npm run lint && npm test && cd ..
    pytest tests/unit/ -v
    
  4. Push your branch to your fork and open a PR against main on the upstream repo.

  5. Fill in a clear description of what changed and why.

  6. CI will run backend tests, frontend tests, E2E tests, and Ruff lint automatically.

Thanks for helping make Dune Weaver better!