Development

full-count is a small Rust application — a handful of modules, one binary, no workspace members. If you're comfortable with cargo you already know how to build it.

Building

cargo build                               # debug
cargo build --release                     # optimized
cargo build --release --features advanced-stats

Running tests

cargo test                                # standard suite
cargo test --features advanced-stats      # feature-gated paths too

CI (GitHub Actions) runs both test lines on every push and pull request, plus cargo fmt --check and cargo clippy -- -D warnings.

Lint & format

cargo fmt                                 # apply rustfmt
cargo clippy -- -D warnings              # treat warnings as errors
cargo clippy --features advanced-stats -- -D warnings

Module layout

FileResponsibility
src/main.rsEntry point, CLI parsing, terminal setup, event loop.
src/app.rsTop-level App state: screens, input modes, setup data, undo stack.
src/game.rsThe GameState domain model: innings, runners, stats, substitutions, and the rules.
src/input.rsPer-screen key handlers; the state machine that turns keystrokes into app/game mutations.
src/ui.rsratatui rendering for every screen.
src/persist.rsJSON save/load and the ~/.full-count/saves/ directory logic.
src/export.rsAskama-driven HTML scorecard export.
templates/scorecard.htmlThe Askama template used by export.rs.

Contributing

Keeping the docs in sync

Docs are first-class. When you change the user-facing behavior of the app, the documentation site in docs/ has to move with it. The rules:

Automation backing these rules lives in AGENTS.md and .github/copilot-instructions.md so every AI-assisted change is nudged into updating the site. Please keep those files honest.

Changelog & releases

Release notes live in CHANGELOG.md on GitHub. Prebuilt binaries for Linux, macOS, and Windows are attached to each entry on the Releases page.

Both are generated automatically by release-plz from Conventional Commit messages on master — there is nothing to hand-edit on this page.

How releases happen

  1. Land commits on master with conventional subjects (feat:, fix:, feat!:, etc.).
  2. release-plz opens or updates a chore: release pull request with the next version, a refreshed Cargo.lock, and the new CHANGELOG.md entry.
  3. Merging that PR tags the release and creates the GitHub Release.
  4. The tag triggers the release workflow, which builds the three OS binaries and attaches them to the release.