Developers
Contributing
Fork, branch, open a pull request — the workflow, the quality gates, and what makes a PR easy to merge.
Contributions go through the standard GitHub fork flow against core (Symfony API) and client (React SPA). Both repos are MIT-licensed.
The flow
- Fork & clone
Fork the repo you’re changing on GitHub, clone your fork, and add the upstream remote:
git remote add upstream git@github.com:tyto-chat/<repo>.git. - Set up the dev environment
Both repos ship a one-command DDEV environment —
ddev startplusddev init(core) orddev setup(client) gives you a running stack with test data tooling. - Branch from master
git switch -c fix/what-you-are-fixing upstream/master. Keep one topic per branch. - Make the change — with tests
Behavior changes come with a test that fails without the fix. Follow the code guidelines and the patterns already next to your change.
- Run the gates locally
The same checks CI runs (see below). Green locally means no surprise on the PR.
- Push to your fork & open the PR
Target
master. Describe what changed and why; link the issue if one exists. CI runs automatically on pull requests.
Quality gates
Core:
ddev test # PHPUnit — unit, functional, integration
ddev composer phpstan # static analysis (level 7)
ddev composer checkcs # code style (auto-fix: ddev composer fixcs)
Client:
ddev npm test # Vitest unit tests
ddev npm run typecheck # strict TypeScript, includes tests/
ddev npm run lint # ESLint
ddev npm run format:check # Prettier (fix: npm run format)
ddev e2e # Playwright — needs the core stack running
Scope formatting to the files you touched — a repo-wide reformat buries the actual change.
Commit style
Conventional prefixes, imperative mood, body explains the why:
fix(channels): reject archiving the welcome channel
Archiving it silently broke the welcome flow — the bot posted into
a frozen channel. 422 with a translated message instead.
feat / fix / refactor / test / docs / chore cover nearly
everything.
What makes a PR easy to merge
- Small and focused — one concern, reviewable in one sitting. Split big work into a series.
- Tests tell the story — the diff shows the behavior change; the test proves it.
- No drive-by changes — no unrelated renames, reformatting or refactors riding along.
- User-facing strings translated — English keys plus, ideally, the other locales; machine-authored translations are accepted and flagged for native review.
For features, open an issue first and sketch the idea — it saves building something that doesn’t land. Bug fixes can go straight to a PR.