# AGENTS.md
Guidance for AI coding agents working on **gitpane**, a multi-repo Git workspace
dashboard TUI (Rust, [ratatui](https://github.com/ratatui/ratatui)). For the
human-facing overview, see [README.md](README.md).
## Setup
- Rust edition 2024, MSRV **1.88.0**. Install a matching toolchain (rustup recommended).
- No services or network access are needed to build, run, or test.
- Full integration coverage requires `git` on PATH, plus `sh` and `sleep` on
Unix. CLI tests use `crate::git::git_test_available()` to skip only missing
Git, with a reason visible under `--nocapture`; broken Git must fail tests.
- Optional tooling for the full local suite: `cargo install cargo-audit cargo-llvm-cov`,
plus [`just`](https://github.com/casey/just) for the task recipes below.
## Build and run
```bash
just run # or: cargo run
cargo build --release
```
## Checks (run before every commit)
```bash
just ci # fmt + lint + docs + test, the full gate
# or individually:
just fmt # cargo fmt --all
just lint # cargo clippy --all-targets --all-features -- -D warnings
just test # cargo test --all-targets --all-features
just docs # rustdoc with -D warnings
```
CI runs the same checks and treats every warning as an error, so `just ci` must
pass before you push. Tests are inline `#[cfg(test)]` modules in the binary
target, so a plain `cargo test --lib` finds nothing. Use `just test` or
`cargo test --bin gitpane`.
For changes to tests or subprocess dependencies, also run
`python3 scripts/check_test_environment.py` on Linux or macOS. This runs every
test harness with only `sh` and `sleep` on its PATH. Missing-Git skips count as
passed in Rust's summary, so the normal suite with Git remains required.
Before a release, also run `python3.14 scripts/check_source_package.py`. It
extracts the Cargo source archive into a temporary directory and runs its tests
with a fresh build target, including the no-Git check on Unix. CI runs this on
Linux, macOS, and Windows, and publication requires all release checks to pass.
## Pre-commit hooks (required)
Install them before contributing:
```bash
pre-commit install # installs the pre-commit and pre-push hooks
```
The pre-commit hook runs file hygiene, TOML/YAML checks, `cargo fmt`, `cargo
clippy`, and the two project rules below. The pre-push hook runs tests, audit,
docs, and coverage.
## Hard constraints
- **Every source file stays under 1000 lines.** When a file approaches the limit,
split it: turn `foo.rs` into a `foo/` directory module and re-export the public
items from `foo/mod.rs` so external paths such as `crate::foo::Bar` do not
change. Do not add exclude lists to dodge the limit; split the file.
- **Every directory under `src/` holds at most 10 files.** Group related modules
into a subfolder rather than letting a folder sprawl. A subfolder's files count
toward the subfolder, not its parent.
- **No warnings.** clippy runs with `-D warnings`. Fix the cause; do not paper over
it with `#[allow(...)]` unless there is a documented reason.
- Refactors that relocate code must be behavior preserving: keep the move
mechanical, re-export to preserve public paths, and keep the test count identical.
## Architecture
Message passing: terminal and filesystem events become `Event`s, the app
dispatches `Action`s, and components update and render. See the diagram and module
map in [README.md#architecture](README.md#architecture). Key areas:
- `src/app/` main loop and action dispatch (`handle_action` / `handle_action_rest`),
launching, input handling, and rendering.
- `src/components/` ratatui widgets, each implementing the `Component` trait.
- `src/git/` libgit2 (`git2`) status, graph, and commit diffs, run inside
`tokio::task::spawn_blocking` to keep the UI responsive.
- `src/session/` tmux and terminal session integration (launcher and liveness).
- `src/config/` TOML config load/save and the terminal auto-detect table.
## Conventions
- Conventional commit subjects: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`,
`test:`, `build:`. Keep each commit focused and leave the tree building and green.
- Test behavior and outcomes, not internals, and put tests next to the code they
cover.
- Prefer a pure, testable core: a function returns a plan or value, and a thin
caller performs the I/O (see `src/session/launcher/mod.rs`).
- Validate or quote any user input that reaches a shell. argv launches avoid the
shell entirely; `sh -c` paths quote every substituted value.
- Use `crate::git::process::git_command(path)` for repository-scoped Git
subprocesses, including test fixtures. It clears inherited hook variables
so commands cannot target the calling repository instead of `path`.
## Pull requests
- Open an issue first (bug report or feature request) and reference it with
`Closes #<n>` in the PR body. Skip the issue only for trivial fixes (typos,
doc tweaks).
- The web UI pre-fills `.github/PULL_REQUEST_TEMPLATE.md`, but `gh pr create`
does not — structure the PR body yourself with the template's sections:
`Closes #<n>`, `## In simple terms` (one or two sentences a user
would understand), `## Problem`, `## Fix`, `## Test`.
## Releasing
Releases are tag driven. Pushing a `vX.Y.Z` tag triggers
`.github/workflows/release.yml`, which builds the platform binaries, creates the
GitHub Release from the matching `CHANGELOG.md` section, and publishes to
crates.io. Do not publish manually.