Thank you for your interest in contributing. See docs/development-environment.md for setup.
pnpm install
pnpm run dev # Development mode
pnpm run build # Production build
pnpm run lint # ESLint
pnpm run test:run # Run testsBefore each commit, the hook runs (order matters):
pnpm run format— Prettier writes fixespnpm run lint:md— Markdown fixes- Re-stage staged files
pnpm run lintpnpm run typecheckcheck:log-injection,check:db-migrations,check:ipc-contract,check:licensespnpm auditactionlint,yamllintpnpm run test:run
Skip in emergency: git commit --no-verify.
Every interactive element needs aria-label. Key rules:
<button>icon-only:aria-label="Action description"<input>/<select>:<label htmlFor="id">oraria-label- Modal:
role="dialog" aria-modal="true" - Error:
role="alert"
pnpm run test:run # Run once
pnpm test # Watch modeRenderer tests use jsdom (src/renderer/**/*.test.{ts,tsx}). Main tests use node (src/main/**/*.test.ts).
- Describe your changes and what you tested
- Update docs if needed
- Run
pnpm run lintandpnpm run test:runfirst - Keep PR scope tight
- A maintainer will review
AI assistants (Claude Code, GitHub Copilot, etc.) are welcome for brainstorming and drafts. However:
- All AI-generated code must be reviewed and tested by a human before merging
- Never accept AI-generated IPC code without understanding it — Electron IPC security is a known weak spot
- Note briefly in the PR if you used an AI tool
By contributing, you agree to license under the MIT License.