Skip to content

Contributing

Contributions are welcome — bug fixes, new features, plugins, themes, or documentation improvements. Here's how to get set up.

Prerequisites

  • macOS 12 Monterey or later (the bridge requires macOS)
  • Python 3.11+ from python.org
  • Node 22+ (for frontend development)
  • Git

Dev install

git clone https://github.com/allenbina/chatwire.git
cd chatwire

# Create a virtualenv and install in editable mode with dev dependencies
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

# Install the launchd agents (renders plists from templates)
.venv/bin/chatwire install-agents

# Verify the setup
.venv/bin/chatwire doctor

The [dev] extra includes pytest and the test dependencies.

Frontend development

The React SPA is in web/frontend/. It's built with Vite.

cd web/frontend

# Install Node dependencies
npm install

# Start the dev server with HMR (hot module replacement)
npm run dev

# Build for production (output to web/frontend/dist/)
npm run build

# Run type checking
npm run typecheck

# Run vitest
npm run test

The Vite dev server runs on port 5173 and proxies API requests to the chatwire web server on 8723.

Running tests

Python tests

# Run all tests
.venv/bin/pytest tests/ --tb=short -q

# Run a specific test file
.venv/bin/pytest tests/test_cli.py -v

# Run with coverage
.venv/bin/pytest tests/ --cov=. --cov-report=term-missing

Tests live in tests/. The conftest.py at the repo root adds the project directory to sys.path.

Frontend tests

cd web/frontend
npm run test          # vitest in watch mode
npm run test -- --run  # single pass (CI mode)

E2E tests

cd web/frontend
npx playwright test           # run all E2E tests
npx playwright test --headed  # run with browser visible

Playwright tests are in web/frontend/e2e/.

Mobile tests

cd packages/mobile
npm run test  # Jest

Project structure for contributors

Key files to understand:

File What it does
bridge.py The poll loop and integration fan-out — start here for bridge behavior
chat_db.py All chat.db queries — start here for message reading
chat_send.py AppleScript send + fuse guard — start here for sending
rules.py Automation rules engine
web/main.py FastAPI app, middleware, health endpoints
web/api_v1.py REST API — all /api/v1/* routes
web/frontend/src/pages/ChatPage.tsx Main chat UI
web/frontend/src/components/MessageList.tsx Virtualized message list

Making changes

  1. Fork the repository on GitHub
  2. Create a branch from main: git checkout -b my-feature
  3. Make your changes — keep the scope focused
  4. Run the tests: pytest tests/ -q && cd web/frontend && npm run test -- --run
  5. Run chatwire doctor to verify the bridge still works
  6. Commit with a clear message: git commit -m "fix: correct whitelist check for group chats"
  7. Push and open a PR against main

PR guidelines

  • Keep PRs focused — one thing per PR
  • Include a description of what changed and why
  • If it's a bug fix, describe how to reproduce the bug
  • If it's a new feature, describe the use case
  • Don't add dependencies without discussing in an issue first
  • All tests must pass

Code style

  • Python: PEP 8, type annotations where practical, f-strings
  • TypeScript: strict mode, no any without comment explaining why
  • No print() in production code — use self.log_info() in plugins, log.info() in web code
  • Existing code is the style guide — match what's already there

Building plugins

If you're building a plugin rather than contributing to core, see Plugin SDK. You don't need to fork the main repo — plugins are separate Python packages.

Issues and discussions

  • Open issues — bugs, feature requests
  • For large features or design questions, open an issue to discuss before coding

License

MIT. All contributions are licensed under MIT.