# Contributing to shuire

Thanks for your interest in contributing! This document describes how to set
up a development environment, the expectations around code quality, and the
pull-request workflow.

## Getting started

### Prerequisites

- Rust toolchain (stable, Rust 1.85 or newer — the project uses edition 2024)
- `git`
- A POSIX-like shell (the TUI uses `/dev/tty` for stdin re-attach on Unix)
- The [`gh`](https://cli.github.com/) CLI is required at runtime for the
  `--pr` feature

### Using the Nix flake (recommended)

A `flake.nix` is provided that pins a known-good Rust toolchain with
`rust-analyzer`, `clippy`, and `rustfmt`:

```sh
nix develop
```

### Using rustup directly

```sh
rustup toolchain install stable
rustup component add clippy rustfmt
```

## Building and running

```sh
cargo build
cargo run -- .          # diff of all uncommitted changes in the current repo
cargo run -- --help
```

## Code quality

Before opening a pull request, please run:

```sh
cargo fmt --all
cargo clippy --all-targets --all-features --workspace -- -D warnings
cargo test --locked --all-features --workspace
```

CI enforces all three. Formatting is expected to match `cargo fmt` output
exactly (including any project-level overrides declared in `rustfmt.toml`).

## Testing

- Unit tests live alongside the code they exercise (`mod tests` blocks).
- Integration tests go under `tests/`. They may invoke the compiled binary
  via [`assert_cmd`](https://crates.io/crates/assert_cmd).
- Fixture diff data goes under `testdata/`.

When fixing a bug, please include a regression test whenever the change is
testable without an interactive TTY.

## Commit messages

We follow the
[Conventional Commits](https://www.conventionalcommits.org/) style used by
existing history:

```
<type>(<scope>): <subject>
```

Common types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `ci`.

Examples from the current log:

```
fix(cli): make --clean wipe saved comments up front
fix(ui): shade shorter side's padding rows in split view
```

Keep the subject line under ~72 characters and focused on a single change.

## Pull requests

1. Fork the repository and create a topic branch off `main`.
2. Make your change, with tests where feasible.
3. Run `cargo fmt`, `cargo clippy`, and `cargo test` locally.
4. Open a pull request. Draft PRs are welcome for early feedback.
5. Describe the motivation and the user-visible effect in the PR body. Link
   to any related issues.
6. Keep commits focused; squash fix-ups before requesting a final review.

## Reporting bugs and requesting features

Please use the GitHub issue templates under
[`.github/ISSUE_TEMPLATE/`](.github/ISSUE_TEMPLATE). For bugs, include:

- `shuire --version`
- OS and terminal emulator
- Exact command that was run
- Expected vs. actual behavior
- A minimal diff or repository that reproduces the problem, if possible

## Release process

`shuire` is distributed as:

- a Rust crate on [crates.io](https://crates.io/crates/shuire)
- an npm package on [npmjs.com](https://www.npmjs.com/package/shuire) (thin
  wrapper that pulls in a prebuilt binary per platform via
  `optionalDependencies`)
- prebuilt tarballs attached to GitHub Releases

To cut a release:

1. Bump `version` in `Cargo.toml` (and commit).
2. Tag the commit as `vX.Y.Z` and push the tag.
3. The CD workflow (`.github/workflows/cd.yml`) will, per platform:
   - Build the release binary.
   - Upload a tarball + SHA-256 to the GitHub Release.
   - Rewrite `npm/shuire-<os>-<arch>/package.json` with the tag version and
     `npm publish` the platform package.
4. Once all platform packages have published, the workflow publishes the
   `shuire` meta package (whose `optionalDependencies` are re-pinned to the
   new version) and the `shuire` crate to crates.io.

Secrets required:

- `NPM_TOKEN`: automation token from an npm account with publish rights to
  `shuire` and the `shuire-<os>-<arch>` packages. Provenance is enabled, so
  the GitHub Actions OIDC token is also consumed automatically.
- `CARGO_REGISTRY_TOKEN`: crates.io API token.

## npm package layout

```
npm/
  shuire/                       # meta package with Node shim (bin/shuire.js)
  shuire-linux-x64/             # prebuilt binary, os/cpu-constrained
  shuire-linux-arm64/
  shuire-darwin-x64/
  shuire-darwin-arm64/
  shuire-win32-x64/
```

The `bin/` directory in each platform package is empty in git (tracked via
`.gitkeep`); CD drops the compiled binary in at publish time.

## License

By contributing, you agree that your contributions will be licensed under
the [MIT License](LICENSE).
