Contributing to Mesh Client
Thank you for your interest in contributing.
| Topic | Document |
|---|---|
| Clone, prerequisites, commands, test harness, git hooks, i18n | docs/development-environment.md |
| Code style, testing, architecture, security (AI assistants) | AGENTS.md |
| Protocol additions (RF mesh only) | Protocol scope |
| PR flow and contribution expectations | This file |
Code style & standards
- Prettier: Semi always, single quotes, trailing commas, print width 100, tab 2, LF.
- TypeScript: Strict; avoid
any; preferunknown+ guards; export types; prefer interfaces over type aliases. - React: Function components only;
exhaustive-depsis errors;?.in JSX; every interactive control needsaria-label. - Colors: Use Tailwind CSS utility classes (e.g.,
text-green-400,bg-slate-700). Custom theme colors via CSS custom properties fromstyles.css(--color-brand-green,--color-deep-black, etc.). Avoid inline hex colors in JSX. End users can also customize theme tokens (including message action colors) under App → Appearance → Colors. - Zustand: Module-level defaults for stable refs; prefer
useStore(s => s.field)over broad subscriptions; avoid subscribing to whole Maps when one id suffices;persistfor localStorage, IPC from an effect for SQLite; extract time constants tosrc/renderer/lib/timeConstants.ts(e.g.MS_PER_SECOND). - Performance: No hot-path O(n); lazy cleanup when collections grow large.
Testing protocols
See Test harness setup and local quality checks for Vitest projects, pre-PR commands, and browser dev stub behavior.
- Renderer: jsdom (
src/renderer/**/*.test.{ts,tsx}). Main (node project):src/main/**/*.test.ts, plussrc/shared/**,src/preload/**,src/architecture/**,scripts/**/*.test.mjs, andvitest.harness.test.ts(seevitest.config.mts). - Reticulum sidecar (Rust): when editing
reticulum-sidecar/**, runpnpm run reticulum:sidecar:clippy:fullbefore PR; CI enforces line coverage intests.yamlwhen sidecar paths change (see docs/development-environment.md). - Mock console before spying logged errors (e.g.
vi.spyOn(console, 'warn').mockImplementation(() => {}); usebeforeEachwhen shared). - Update
src/main/index.contract.test.tswhen CSP, build config, IPC limits, or log filters change. - Accessibility: vitest-axe in component tests; see Accessibility / axe in AGENTS.md.
Protocol scope
Mesh-Client focuses on RF mesh networking (LoRa and related radio meshes). Additional protocols are in scope when they support that kind of RF mesh path. Internet-only messaging is out of scope. Ham protocols are welcome under the same RF-mesh criteria; Mesh-Client is for everyone, everywhere, and is not gated or targeted specifically at people with a ham radio license. Protocols that already ship may still use internet transports alongside RF. Product framing: README — Why.
PR process
- Describe your changes and what you tested
- Update docs if needed
- Run the checks you need before review — at minimum the local quality checks and what the pre-commit hook runs
- Keep PR scope tight
- A maintainer will review
AI-assisted contributions
Follow AGENTS.md for mesh-specific and security expectations, and this file for code style and testing conventions. Review every line of AI-generated code before merging. Do not accept AI-generated IPC or preload changes without understanding them (Electron IPC is a common weak spot). You may note briefly in the PR if you used an AI tool.
Avoid duplicating always-on Cursor or editor rules with this repo's docs; merge overlaps and prefer requestable rules over always-on where possible to reduce fixed context size.
By contributing, you agree to license under the MIT License.