egui-nonogram 0.4.0

A nonogram (picross) puzzle game library for egui
Documentation
# AGENTS.md

Instructions for AI coding agents working in this repository.

## What this is

`egui-nonogram` is a self-contained Rust library that implements a nonogram
(picross) puzzle game for [egui](https://github.com/emilk/egui): renderer-agnostic
game logic plus a ready-to-use `egui::Widget`. It has no application of its
own beyond the demo in `examples/webapp.rs` — it's meant to be pulled into
other egui apps as a dependency.

## Module layout

- `src/game.rs` — `NonogramGame`, `CellState`, `GameStatus`, `Clue`. Pure
  logic, no `egui::Widget`/`Ui` usage. Keep it that way: it should stay
  usable headlessly (e.g. for tests or a non-egui renderer) without pulling
  in any painting code.
- `src/widget.rs` — `NonogramWidget`, `TapMode`, and all painting/input
  handling. This is the only file allowed to depend on `egui::Ui`/`Painter`.
- `src/lib.rs` — thin re-export surface. `#![doc = include_str!("../README.md")]`
  means the crate-level docs are the README; keep the two in sync (usage
  snippets especially).
- `examples/webapp.rs` — a wasm demo app (via `xtask-wasm`), deployed to
  GitHub Pages by `.github/workflows/pages.yml` on every push to `main`.
  Not part of the published crate (`Cargo.toml` excludes `/examples`).

## Building and testing

```sh
cargo check
cargo test --lib
cargo clippy -- -D warnings
cargo fmt --check
```

These four are exactly what `.github/workflows/ci.yml` runs on every push
and PR. Run them locally before committing.

The wasm demo isn't covered by `ci.yml` (only `pages.yml` builds it, on
push to `main`). If you touch `examples/webapp.rs`, check it manually:

```sh
cargo check --target wasm32-unknown-unknown --example webapp
cargo clippy --target wasm32-unknown-unknown --example webapp -- -D warnings
```

## Conventions

- Monochrome only (no per-cell color/palette). `CellState` is `Empty` /
  `Filled` / `Crossed`. If color support is ever added, do it as a new,
  additive API — don't break the existing monochrome one.
- No losing state. Every player action must be reversible; the game only
  transitions `Playing` -> `Won` (or back, if an undo reverts a winning move).
- `Crossed` cells are a player aid and must never be required to match the
  solution for a win — only `Filled` cells are checked.
- Add unit tests in `src/game.rs` for any new game-logic behavior (clue
  computation, win detection, generation). The widget/painting code isn't
  unit-testable in the same way; verify it by eye via the wasm demo.
- Keep the crate's public API renderer-agnostic where possible: prefer
  exposing queries (`row_satisfied`, `is_solution_filled`, etc.) over raw
  field access, so the internal representation can change without breaking
  callers.

## Release process

Every published version gets a git tag and a changelog entry. To cut a release:

1. Update `CHANGELOG.md`: move the `[Unreleased]` section's contents under
   a new `## [X.Y.Z] - YYYY-MM-DD` heading (Keep a Changelog format), and
   add the corresponding link reference at the bottom of the file.
2. Bump the `version` in `Cargo.toml` to match.
3. Run the full check suite above, plus `cargo package --list` as a final
   sanity check of what will actually be published.
4. `cargo publish`. This is irreversible per-version (a bad release can
   only be `cargo yank`-ed, not deleted) — don't skip step 3.
5. `git tag vX.Y.Z && git push && git push --tags`.

Follow SemVer: breaking changes (renamed/removed public items, changed
method signatures) require a major version bump (or a minor bump pre-1.0,
per SemVer's pre-1.0 rules).