Skip to content

Latest commit

 

History

History
109 lines (87 loc) · 5.69 KB

File metadata and controls

109 lines (87 loc) · 5.69 KB

Contributing to openGym

Thanks for taking a look. openGym is deliberately small and light on dependencies, and the aim is to keep it that way: easy to read, easy to self-host.

Project layout

frontend/  React + Vite app (src/views, src/components, src/store, src/lib). Builds to static files.
           android/ and ios/ are the Capacitor shells for the standalone app (docs/MOBILE.md).
api/       Backend: server.js on plain node:http, two dependencies (@simplewebauthn/server, web-push).
           coach/ is the optional AI coach; openapi.yaml documents every route.
web/       Multi-stage Dockerfile (builds the frontend, serves it with nginx) and the nginx template.
mcp/       Optional read-only MCP server for LLM clients (Claude Desktop, Cursor, ...). Not in the
           Docker build; it only runs when a client spawns it. See mcp/README.md.
website/   The static project site at opengym.duarte-santos.ch.
kubernetes/ Example manifests (docs/SELF_HOSTING_KUBERNETES.md).
docs/      User and operator guides (index: docs/README.md); docs/dev/ has feature design notes.
media/     Exercise images and GIFs, gitignored and fetched at runtime.

Running for development

cp .env.example .env
docker compose up -d --build      # api + web + media on :8080

cd frontend && npm install && npm run dev   # hot reload, proxies /api to :3000
cd frontend && npm test                     # training logic, locales, components
cd api && npm test
cd mcp && npm test

Guidelines

  • Keep it dependency-light. The frontend uses React, React Router and Zustand; api/ has two dependencies. A new dependency on either side is a hard sell.
  • Match the style. Small components, clear names, comments only where the why isn't obvious. State lives in the Zustand store (src/store), pure helpers in src/lib. There is no linter or formatter config, so follow the surrounding code.
  • Don't commit media/ or data/; both are gitignored.
  • Click through what you touched, including the workout flow, in a browser before opening a pull request.
  • Training logic gets a unit test. Anything that decides what you lift next, or reads a logged session back, belongs in a pure helper in src/lib with a test beside it. These rules are easy to get subtly wrong and nearly impossible to check by clicking; the progression engine has had real bugs that only a test caught.
  • New UI strings go into every locale in frontend/src/locales/. English is the source language and has no file. node scripts/check-locales.mjs (run in CI) flags a key that is missing, blank or has lost a {n} placeholder. Portuguese (Brazil) inherits from Portuguese (Portugal) and has its own guard test.

Using AI tools

openGym itself is developed with Claude Code (see How openGym is built), and CLAUDE.md holds the project context for it. You're welcome to use whatever tools you like for a pull request. The bar is the same either way: you understand the change, it's tested, and you can answer questions about it in review.

What CI does with your pull request

CI path: pull request on GitHub, GitHub Actions tests and image builds, review and merge into main, mirror workflow pushes to GitLab, GitLab CI builds the signed APK, images and SBOMs, GHCR images on release.

A pull request runs the three test suites and builds and boots both api image targets. The APK and the published images come from GitLab CI on the mirror, built from main after the merge. If your change needs an APK to be judged, say so in the pull request and a maintainer will run that build. A first-time contributor's workflows wait for a maintainer to approve them, so "no checks yet" just means nobody has pressed the button.

Merge requests still open on the GitLab mirror are reviewed too and land on main here. New work should come as a GitHub pull request.

Good first issues

  • More starter plans
  • More languages for the exercise instructions (the dataset ships several)
  • Percentage or training-max programming (5/3/1 style) on top of the progression engine in src/lib/progression.js; the policy interface is already there
  • Accessibility passes on the workout and chart screens

Where to ask what

You have Goes to
A quick question, or you'd rather chat Discord
A question, or self-hosting that won't behave Discussions → Q&A
An idea you're not sure about yet Discussions → Ideas
A reproducible bug Issues
A change you've already built A pull request
A security problem Private report, see SECURITY.md

An answered question in Discussions is worth more than the same answer in a chat log, because the next person searching "passkey login fails behind my reverse proxy" finds it. If a Discord answer turns out to be worth keeping, it belongs in Discussions afterwards.

Reporting bugs

Open an issue with what you did, what you expected, what happened, and your browser and OS. For login or passkey problems, include your RP_ID and ORIGIN (not the contents of data/); most login issues are an origin mismatch.

By contributing you agree that your work is licensed under the project's GNU AGPL v3.0.