Contributing Guide
This guide explains how to contribute changes that are easy to review, test, and include in release notes.
Workflow
- Create a branch from
main. - Run local checks (see below) before pushing.
- Implement your change with focused commits.
- Open a pull request.
- The template for the notes is in
.github/pull_request_template.md. - Apply at least one release label.
- Wait for CI checks to pass.
- If they fail, push updates to the PR to fix them before they can be merged.
PRs
- Keep PRs scoped and readable.
- Prefer clear PR titles (they are shown in generated release notes).
- Keep PR body to
## Release Notesbullets only (using.github/pull_request_template.md).
CI Behavior
- PRs to
main: run test suite without Playwright E2E. - Push to
main: run test suite without Playwright E2E, then build/publishlatestDocker image. - Published release: run full suite including Playwright E2E before stable Docker build.
Local Testing
Try testing the code you changed first:
If the scoped tests pass, run the global tests:
If your change affects LLM connectivity, you can optionally run a live provider connectivity check.
Note: only runs when relevant API keys are present in local .env.
Documentation and Linting
- Update docs when behavior or setup changes.
- Keep edited markdown compliant with
.markdownlint.json.
UI Translations
UI copy lives in src/lib/i18n/en.js. This English file is the source of truth for all other locale files in src/lib/i18n/.
The app language selector options come from src/lib/utils/config.js, which in turn derives from languageLabels in the ingredient parser submodule. The locale registry used by the UI translator lives in src/lib/i18n/index.js.
When you add or rename UI keys:
- Update
src/lib/i18n/en.js. - Regenerate locale files with the incremental generator:
Useful flags:
--langs=deu,ita,...limits generation to specific languages.--namespaces=common,nav,...limits generation to specific top-level namespaces.--overwriteforces regeneration even when a namespace already looks current.
Generator behavior:
- It only submits missing, stale, shape-mismatched, or still-English namespaces.
- It validates key shape and placeholder tokens such as
{count}and{name}. - It retries automatically when the model returns invalid JSON or drops placeholders.
After generation:
- Spot-check the changed locale files for obviously bad output.
- Run:
If you are adding support for a brand new language rather than updating existing locale files:
- Add the language to the ingredient parser language metadata so it appears in
languageLabels. - Add the matching locale module in
src/lib/i18n/. - Register it in
src/lib/i18n/index.js. - Confirm it appears in the settings language dropdown via
src/lib/utils/config.js.