# Contributing to BandReady Thanks for helping. BandReady is a local-first desktop app: an Electron shell around a React renderer, talking to a Python FastAPI sidecar over loopback HTTP. This document covers how to get running, where things live, and the seams you extend rather than edit. Two of those seams are auto-discovered, so adding a route or a screen never means editing a registry. A third pipeline, the content pack, has the opposite rule: its output files are generated and must never be hand-edited. Sections 3, 4 and 5 are the ones to read before your first change. Before anything non-trivial, read [`docs/plan/README.md`](docs/plan/README.md). The design is written down in full, module by module, and most "why is it like this?" questions are answered there. [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) covers dev-mode architecture and debugging. Everyone taking part is expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md). If you think you have found a security problem, do not open a public issue; [SECURITY.md](SECURITY.md) has the private route. --- ## 1. Dev setup | Tool | Version | |---|---| | Node.js | 20 or newer | | pnpm | 9 (`corepack enable && corepack prepare pnpm@9.12.0 --activate`) | | Python | 3.11 | | uv | latest | ```bash pnpm install # JS workspace cd sidecar && uv sync --extra dev --extra voice # Python sidecar (drop --extra voice for cd .. # a text-only install, 2 to 3 GB smaller) node scripts/dev.mjs # Electron + Vite + sidecar node scripts/dev.mjs --browser # sidecar + Vite only, no Electron ``` `--browser` runs the sidecar on a fixed port (8710) with a fixed token (`dev-token`) and mock providers enabled, and serves the SPA at `http://127.0.0.1:5273`. It is the mode the E2E suite drives, and the fastest way to poke at the API with `curl`. Dev-mode state lives in `.dev-data/` at the repository root. It holds downloaded model weights, the SQLite database, the sidecar's auth secret and any recordings of your voice, so it is gitignored and must stay that way. [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) section 5 has the safe reset procedure. ## 2. Repository map ``` bandready/ ├── app/ Electron shell + React renderer (pnpm workspace "bandready-app") │ ├── electron/ main.ts, preload.ts, sidecar.ts (spawn/health/teardown), │ │ ipc.ts, update.ts. The Node side, never imported by the SPA. │ └── src/ │ ├── App.tsx route auto-discovery. DO NOT EDIT to add a screen. │ ├── components/shell/ Sidebar (nav auto-discovery), PageShell, error boundary │ ├── components/ui/ the design-system kit (Button, Card, Modal, BandScore, │ │ CircularTimer, QuestionPalette, Heatmap, and the rest) │ ├── features// one folder per screen: route.tsx, page.tsx, store.ts, │ │ components/, __tests__/ │ ├── lib/ api.ts (the only HTTP client), featureRoute.ts, cn.ts, │ │ format.ts, theme.ts │ ├── stores/ global zustand stores: settings, session, progress, srs │ └── styles/ Tailwind entry + design tokens ├── sidecar/ │ ├── bandready/ │ │ ├── server/ │ │ │ ├── app.py the app factory + route auto-discovery. DO NOT EDIT to add │ │ │ │ a route. │ │ │ ├── routes/ one module per API family; every one is imported automatically │ │ │ ├── auth.py loopback + origin + bearer guards │ │ │ ├── deps.py require_auth, current_profile_id, get_session │ │ │ ├── errors.py ApiError + the JSON error envelope │ │ │ ├── jobs.py the 202 + poll job manager │ │ │ └── tickets.py short-lived signed tickets for