# Contributing to ezpn

Thanks for the interest. ezpn is an opinionated tmux successor — small surface, fast iteration, native feel. The bar for contributions is correctness + zero regressions in attach/detach/render.

## Quick start

```bash
git clone https://github.com/subinium/ezpn
cd ezpn
cargo build
cargo test
cargo run -- 2 2          # try a 2x2 grid
```

MSRV: **Rust 1.82**.

## Workflow

1. **Open an issue first** for non-trivial changes (anything that touches `daemon`, `protocol`, `render`, snapshot schema, or `.ezpn.toml` schema). Drive-by PRs without an issue may be closed.
2. **Branch from `main`.** GitHub Flow — no `develop`. Branch name matches the change type:

   | Prefix | Use for |
   |---|---|
   | `feat/` | New user-facing capability |
   | `fix/` | Bug fix |
   | `perf/` | Performance improvement |
   | `refactor/` | Structural change, no behavior change |
   | `chore/` | Build, deps, CI, release |
   | `docs/` | README, translations, comments |
   | `test/` | Tests only |

   Example: `feat/scrollback-persistence`, `fix/borderless-off-by-one`.

3. **Make the change small.** One logical change per PR. If "and" appears in the title, split it. Refactor (structural) and feature (behavioral) commits MUST be separated — Tidy First. The reviewer should be able to verify each commit independently.

4. **Run pre-CI locally before pushing:**

   ```bash
   cargo fmt -- --check
   cargo clippy --all-targets -- -D warnings
   cargo test
   cargo build --release
   ```

   Optional but encouraged for `perf/`:

   ```bash
   cargo bench --bench render_hotpaths
   ```

   Attach before/after numbers in the PR description.

5. **Open the PR.** The template is mandatory — every checkbox is a real gate.

## Commit messages

Conventional Commits. Subject in imperative mood, lowercase, no trailing period, ≤ 72 chars.

```
feat(server): negotiate wire-protocol version on attach

Adds a Hello/HelloAck handshake. Older clients fall back to v0
behavior; mismatched majors are rejected with a user-friendly
message instead of silent corruption.

Closes #3
```

Body explains *why*. The diff explains *what*.

## What we will reject

- PRs that mix structural and behavioral changes in one commit.
- PRs that bump MSRV without an issue + justification.
- PRs that add a dependency for a one-line replacement.
- PRs that change snapshot schema or wire protocol without a migration / version bump.
- PRs without `cargo fmt && cargo clippy && cargo test` passing.
- PRs that touch the README without syncing all `docs/README.{ko,ja,zh,es,fr}.md`.

## What we welcome

- Repro fixtures for nasty bugs (a failing test is the best PR).
- Terminal-specific compatibility fixes (with the terminal name + version in the PR body).
- Performance improvements with `criterion` numbers attached.
- Translations and translation fixes — keep the structure identical to English README.

## Release & versioning

- Semantic versioning. `0.MINOR.PATCH` until 1.0.
- Releases are cut from `main` via annotated tags (`vX.Y.Z`) + `gh release create` + `cargo publish`.
- See [`MAINTENANCE.md`](MAINTENANCE.md) for the full release pipeline.

## Code of conduct

Be direct. Be technical. Don't be a jerk. That's the whole rule.
