# Agents
Guidelines for AI agents working on this codebase.
## Project overview
DepsGuard is a zero-dependency Rust CLI that scans package manager configs (npm, pnpm, bun, uv) for supply chain security best practices and offers interactive fixes. It targets Linux, macOS, and Windows.
## Git workflow
- **Never push directly to `main`** without explicit permission from the user. Always use a feature branch and open a pull request.
- Do not force-push or run destructive git operations unless explicitly asked.
## Commit messages
Use **Conventional Commits** ().
Format: `(): `
Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `ci`, `perf`, `style`, `build`.
Examples:
- `feat(manager): add yarn berry support`
- `fix(fix): preserve comments when writing .npmrc`
- `test: add integration tests for bun config`
- `docs: update supported managers table`
- `refactor(term): simplify Windows console FFI`
Rules:
- Use lowercase for the description; no trailing period.
- Keep the subject line under 72 characters.
- Use the body (separated by a blank line) to explain *why*, not *what*, when the change is non-trivial.
- Reference issue numbers in the footer when applicable (`Closes #42`).
## Zero-dependency constraint
This project intentionally has **no external crates**. All functionality (terminal raw mode, TOML editing, ANSI colors, key input) is implemented using only the Rust standard library and platform FFI. Do not add dependencies to `Cargo.toml`.
## Rust conventions
### Code style
- Run `cargo fmt` before committing. All code must pass `cargo fmt -- --check`.
- Run `cargo clippy -- -D warnings` and fix all warnings. Treat clippy lints as errors.
- Prefer `rustfmt` defaults; do not add a `rustfmt.toml` unless there is a strong reason.
### Error handling
- Use `Result` for fallible operations; avoid `unwrap()` and `expect()` in non-test code.
- Prefer descriptive error messages that help the user understand what went wrong and how to fix it.
- In `main`, surface errors with user-friendly messages rather than raw debug output.
### Safety and FFI
- Minimize `unsafe` blocks and document each one with a `// SAFETY:` comment explaining the invariant.
- Keep FFI (termios on Unix, Console API on Windows) isolated in `src/term.rs`.
### Naming and structure
- Follow Rust naming conventions: `snake_case` for functions/variables, `CamelCase` for types, `SCREAMING_SNAKE_CASE` for constants.
- Keep modules focused — see the **How it works** section in `README.md` for module responsibilities.
- Prefer small, composable functions over long procedural blocks.
### Testing
- Run the full test suite with `cargo test` before marking work as done.
- Unit tests go in the same file as the code they test, inside a `#[cfg(test)] mod tests` block.
- Integration tests live in `tests/`. Cross-platform tests that require Wine go in `tests/cross_platform.rs`.
- Test names should read as sentences: `fn detects_missing_npmrc_setting()` not `fn test1()`.
### Cross-platform
- All file path logic must handle Linux, macOS, and Windows. Use `std::path::PathBuf` and `std::env::consts::OS` / `cfg!(target_os = ...)` for platform branching.
- Terminal code must work on both Unix (termios) and Windows (Console API).
### Documentation
- Public functions and types should have a doc comment (`///`).
- Keep comments focused on *why*, not *what*. The code should be self-explanatory for the *what*.
- End-user documentation belongs in **`README.md`** (install, usage, troubleshooting). Maintainer-only topics (tests, releases, package automation secrets) stay here.
## Build & verify
```bash
cargo fmt -- --check # formatting
cargo clippy -- -D warnings # lints
cargo test # all tests
cargo build --release # release binary
```
## Release & distribution (CI secrets)
Pushes to `main` on release-relevant paths run `.github/workflows/release.yml`.
The workflow creates a release tag, publishes artifacts, and runs optional publishers.
| Secret | Purpose |
|--------|---------|
| `CARGO_REGISTRY_TOKEN` | `cargo publish` to crates.io |
| `RELEASE_BOT_TOKEN` | PAT used by release workflow to push Homebrew formula updates directly to `main` |
| `WINGATE_RELEASE_TOKEN` | Open WinGet PRs via WinGet Releaser (requires existing package id + winget-pkgs fork) |
Homebrew formula is now maintained in this repository at `Formula/depsguard.rb`.
On each release, CI renders it from `packaging/homebrew/depsguard.rb.in` and pushes
the updated formula commit directly to `main`.
Both Homebrew and Scoop manifests are maintained in this repository (`Formula/depsguard.rb` and `bucket/depsguard.json`).
Templates live under `packaging/`; render script for Scoop is `scripts/release/publish-scoop-bucket.sh`.
### End-user install channels (optional)
Document these in your org’s internal runbooks or public docs once the repos exist; **do not** duplicate in `README.md` unless you have stable public install channels.
**Homebrew (formula in this repo)**
1. Keep `Formula/depsguard.rb` as the canonical formula path.
2. Release workflow updates formula `url`/`sha256` directly on `main` for each release tag.
3. Users tap with explicit repo URL: `brew tap /depsguard https://github.com//depsguard`.
**Scoop (bucket in this repo)**
1. Scoop manifest lives at `bucket/depsguard.json` (rendered from `packaging/scoop/depsguard.json.in`).
2. Release workflow updates the manifest directly on `main` for each release tag.
3. Users: `scoop bucket add depsguard https://github.com//depsguard` then `scoop install depsguard`.
**WinGet**
- Optional job uses [WinGet Releaser](https://github.com/vedantmgoyal9/winget-releaser) when `WINGATE_RELEASE_TOKEN` is set.
- At least one version of `Arnica.DepsGuard` must exist in [microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) (first manifest is usually manual); the token owner needs a fork of `winget-pkgs`.
**Other templates in-repo**
| Path | Purpose |
|------|---------|
| `packaging/aur/PKGBUILD` | AUR binary package example (`updpkgsums` after release) |
**Releasing a version**
Use release tags in `v` format (for example `v0.1.1`). The current workflow
creates/pushes release tags automatically from `main`.
**Changelog**: Release notes are auto-generated by GitHub (`generate_release_notes: true` in the release workflow). There is no separate changelog tool (git-cliff was previously used but has been removed).