# Contributing to Proxym

Thank you for considering contributing to Proxym! This guide will help you get started.

## Development Setup

```bash
# Clone the repository
git clone https://github.com/wronai/proxy.git
cd proxy

# Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install in development mode
pip install -e ".[dev]"

# Run tests
make test
```

## Project Structure

```
src/proxym/
├── cli/              # CLI commands (Click-based)
│   ├── _groups/      # Click group wrappers
│   └── utils/        # Shared CLI utilities
├── dashboard/        # FastAPI backend
│   ├── tickets/      # Ticket model, manager, persistence
│   ├── tools/        # Tool health, dispatch, executor
│   └── utils/        # Shared helpers (emit_event, etc.)
├── domain/           # CQRS: commands, queries, events, handlers
├── mcp/              # MCP tool integrations (vallm, etc.)
└── tools/            # Tool registry, startup orchestrator
```

## Architecture Overview

```mermaid
sequenceDiagram
    participant CLI as proxym CLI
    participant API as FastAPI Dashboard
    participant TM as TicketManager
    participant TE as ToolExecutor
    participant Tool as AI Tool (aider, claude-code, ...)
    participant ES as EventStore (SQLite)

    CLI->>API: POST /dashboard/tickets {task, tool}
    API->>TM: create_ticket(ticket)
    TM->>ES: persist ticket
    API->>ES: emit TaskCreated event
    API->>TE: enqueue(ticket, tool, project_dir)
    TE->>ES: emit JobDispatched event
    TE->>Tool: spawn process (aider --message ...)
    Tool-->>TE: exit code + output
    TE->>ES: emit JobCompleted / JobFailed
    TE->>TM: update ticket status
    ES-->>API: SSE push to dashboard
```

## Key Concepts

- **Tickets** — unit of work, tracked in `TicketManager` (SQLite-backed)
- **Tools** — AI development tools (aider, claude-code, windsurf, cursor, etc.)
- **Jobs** — queued tool executions, managed by `ToolExecutor`
- **Domain Events** — CQRS event sourcing via `EventStore`
- **SSE** — Server-Sent Events for real-time dashboard updates

## Making Changes

1. **Create a branch** from `main`
2. **Write tests** before or alongside implementation
3. **Run the test suite**: `make test` or `pytest tests/`
4. **Run shellcheck** on bash scripts: `shellcheck examples/todo-app-ts/*.sh`
5. **Check dashboard**: `make check-dashboard` (validates JSX endpoints)

## Code Style

- **Python**: Follow existing patterns. Use `structlog` for logging. Type hints everywhere.
- **Bash**: Use `set -euo pipefail`. Portable POSIX where possible (no `grep -P`, no GNU-only `date`).
- **JSX**: React functional components with hooks. SSE for live updates.
- **Tests**: Use `pytest`. Dashboard singletons use in-memory managers to avoid cross-test state.

## Domain Events

When adding mutations to API endpoints, emit domain events:

```python
from proxym.dashboard.utils._emit_event import emit_event as _emit_event
from proxym.domain.events import TaskCreated

_emit_event(TaskCreated(
    aggregate_id=ticket.id,
    actor="api",
    data={"task": task_text, "priority": priority},
))
```

## CLI Commands

CLI uses Click. Add new commands in `src/proxym/cli/_groups/` and register them in `src/proxym/ctl.py`.

Top-level shortcuts (e.g., `proxym jobs`, `proxym board`) are defined directly in `ctl.py`.

## Ticket Fields

Tickets support `context_files` (files the AI should read) and `depends_on` (ticket dependency graph).

## Questions?

Open an issue or check `docs/` for API documentation, CLI usage, and architecture details.
