# AGENTS.md — Guidance for AI Agents

This file describes the repository structure, conventions, and instructions for
AI coding agents working on the **pman** project.

---

## Project overview

**pman** is a Rust-native port of [Apache Maven](https://maven.apache.org/) for
building and managing Java projects.  
The goals are: faster cold-start, parallel dependency resolution, and a single
self-contained binary with no JVM requirement for the build tool itself.

---

## Repository layout

```
pman/
├── src/
│   ├── main.rs          # CLI entry-point (clap); parses goals and dispatches phases
│   ├── lib.rs           # Re-exports all public modules
│   ├── lifecycle.rs     # Phase enum, phases_up_to(), execute_phase(), BuildContext
│   ├── pom.rs           # Pom / Dependency / Build structs; parse_pom(); property resolution
│   ├── compiler.rs      # Invokes javac for main and test sources
│   ├── dependency.rs    # Downloads JARs from Maven Central; SHA-1 verification
│   ├── packager.rs      # Assembles compiled classes into a JAR (zip crate)
│   └── repository.rs    # Local repository (~/.pman/repository); install_artifact()
├── .github/
│   ├── skills/
│   │   ├── addressing-pr-comments/SKILL.md  # How to address PR review comments
│   │   ├── commits-and-versioning/SKILL.md  # Conventional commits & versioning
│   │   └── pull-requests/SKILL.md           # PR title format & checklist
│   ├── workflows/ci.yml          # PR checks: fmt, clippy, test, build
│   ├── workflows/main.yml        # Tag-triggered release: test + multi-platform builds + GitHub Release
│   └── workflows/release-plz.yml # Conventional commits → auto version bump PR + tag
├── Cargo.toml
├── Cargo.lock
├── CHANGELOG.md         # Maintained automatically by release-plz
├── release-plz.toml     # release-plz configuration
├── AGENTS.md            # Project-specific guidance for AI agents
└── README.md
```

---

## Build, lint, and test commands

All commands must be run from the repository root.

| Purpose | Command |
|---------|---------|
| Build (debug) | `cargo build` |
| Build (release) | `cargo build --release` |
| Run all tests | `cargo test` |
| Check formatting | `cargo fmt --all -- --check` |
| Apply formatting | `cargo fmt` |
| Run linter | `cargo clippy --all-targets --all-features -- -D warnings` |

The CI pipeline runs `fmt --check`, `clippy -D warnings`, and `cargo test` on
every pull request.  **All three must pass before merging.**

---

## Code conventions

### Error handling
- Use `anyhow::Result<T>` for all public and private functions that can fail.
- Attach context with `.with_context(|| format!("…"))`.
- Use `anyhow::bail!` for early exits with a formatted message.
- Do **not** use `unwrap()` or `expect()` in production code paths; they are
  acceptable only inside `#[cfg(test)]` blocks.

### Idioms and style
- Apply `#[must_use]` to every pure method or constructor.
- Add `# Errors` doc sections to every public function returning `Result`.
- Prefer format-string captures (`{var}` over `"{}", var`) everywhere.
- Prefer iterator combinators (`map_or`, `is_some_and`, `filter_map(Result::ok)`)
  over explicit `if let` / `match` when the combinator is clearer.
- Never shadow a variable with the same name — rename the new binding instead.
- Keep function bodies under ~60 lines; extract helpers when they grow longer.

### Trait implementations
- When adding a `from_str`-like method, implement `std::str::FromStr` instead of
  a free-standing method so callers can use `.parse::<Type>()`.

### Adding a new lifecycle phase
1. Add a variant to `Phase` in `src/lifecycle.rs`.
2. Add the variant (in order) to `Phase::all_default()` if it is part of the
   default lifecycle; otherwise handle it as a standalone step.
3. Add an arm to `execute_phase()`.
4. Add a test case in the `#[cfg(test)]` block covering `phases_up_to`.

### Adding a new module
1. Create `src/<module>.rs`.
2. Add `pub mod <module>;` to `src/lib.rs`.
3. Wire any public API into the appropriate lifecycle phase in `lifecycle.rs`.

---

## Dependency policy
- Prefer crates already in `Cargo.toml` before adding new ones.
- Run `cargo audit` before adding a new dependency.
- Pin to a minor version (`"1"`, `"0.31"`) rather than an exact patch.

---

## Versioning & pull requests

See the skill files under [`.github/skills/`](.github/skills/) for detailed guidance:

- **[Commits & Versioning](.github/skills/commits-and-versioning/SKILL.md)** — commit message format, conventional commits, version bump rules
- **[Pull Requests](.github/skills/pull-requests/SKILL.md)** — PR title format and pull request checklist
- **[Addressing PR Comments](.github/skills/addressing-pr-comments/SKILL.md)** — how to handle reviewer feedback without overwriting the PR title/description

---

## Testing guidelines
- Unit tests live in a `#[cfg(test)] mod tests { … }` block at the bottom of
  each source file.
- Use `tempfile::NamedTempFile` / `tempfile::TempDir` for tests that need real
  files; never hard-code `/tmp` paths.
- Tests must not make network calls; stub or skip anything that would hit
  Maven Central.
- Run `cargo test` to confirm all tests pass before opening a pull request.
