Contributing
How to contribute to Murage: ground rules, what a mergeable pull request looks like, platform and security rules, translations, and the CLA.
The CLA
Contributors sign a CLA (Contributor License Agreement). Read it in CLA.md in the repository. It was introduced in pull request #10.
Ground rules
- Small, focused pull requests. One concern per PR. A PR that ports a platform, adds a feature and refactors will be asked to split. For big changes, open an issue first and agree on the approach.
- Match the altitude. Murage is deliberately small and direct: plain Node on the server, no server frameworks, one store, one event bus. Don't add a dependency where thirty lines of code will do. New runtime dependencies need a reason in the PR description.
- Keep it green.
pnpm typecheck && pnpm testmust pass. Server changes need tests. - UI changes need screenshots. Before and after images in the PR, and a video for anything animated. Match the existing palette and tone.
Before you open the pull request
pnpm typecheckandpnpm testpass.- Translation changes pass
pnpm i18n:checkand have been reviewed by a speaker. pnpm check:electronpasses for desktop-shell changes.- Ubuntu packaging changes pass
pnpm package:linuxandnode scripts/verify-linux-package.mjs. - New server behavior has a test; driver changes keep the contract tests green.
- No changes in
dist-server/, and no lockfile changes beyond your actual dependency change. - macOS-only code is platform-gated, and nothing breaks the packaged app.
- UI changes include before and after screenshots.
Platform rules
- The server (
server/) stays portable Node. Anything macOS-only belongs inelectron/behind aprocess.platform === "darwin"check. - The app should use the desktop capability contract rather than guess what's supported from Electron or the user agent.
- Test Ubuntu claims on a real GNOME session. A virtual display proves packaging, not real desktop behavior.
- Linux screen control stays limited to GNOME on Xorg after explicit opt-in, and stays off on Wayland until it passes its input checks.
- Never build command strings for a shell, and give POSIX-only calls a real Windows equivalent.
Secrets
API keys are write-only. They're saved, and the API reports only whether each one is configured. Never log keys, echo them in responses or events, or put them in command-line arguments where another local process could read them.
Tool schemas
Tool input schemas pass through every engine's own lossy conversion. Never use oneOf, anyOf, allOf, const or format in a tool inputSchema. Use one flat object, put per-variant rules in descriptions, accept inputs with one obvious meaning, and make refusals teach with a copyable example.
Adding a language
The app's text lives in JSON files in src/locales/, with English (en.json) as the source of truth.
- Copy
src/locales/en.jsontosrc/locales/<code>.json, using a lowercase language tag such asde.jsonorpt-br.json. Keys you leave out fall back to English. - Register it in
src/locales/index.ts. - Run
pnpm i18n:check, then pick the language in SettingsGeneral.
Only part of the interface is translated so far. Move strings into the catalog as you touch components, not in big sweeps.
Verifying a change
Before claiming a server or conversation change works, use the isolated verification flow in docs/verification/README.md in the repository. Never point test tools at your real ~/.murage.
Ways to help that aren't code
- Report bugs with diagnostics: Collecting a bug report.
- Propose skills and teams for the library: Writing a skill or team for the library.
- Review translations.
Code of conduct and security
The repository has a CODE_OF_CONDUCT.md. Report security problems privately, not in public issues, by following the repository's security policy.
See also: Build from source and Open-source license.