|
| 1 | +# AGENTS.md - Gitclaw Development Guide |
| 2 | + |
| 3 | +> **The Claw is the Law** — This document guides development workflows for the gitclaw project. |
| 4 | +
|
| 5 | +--- |
| 6 | + |
| 7 | +## Repository Structure |
| 8 | + |
| 9 | +``` |
| 10 | +gitclaw/ |
| 11 | +├── .github/workflows/ # CI/CD reusable workflows |
| 12 | +├── src/ # Source code (flat structure) |
| 13 | +├── tests/ # Integration tests |
| 14 | +├── Cargo.toml # Dependencies |
| 15 | +├── README.md # User documentation |
| 16 | +└── AGENTS.md # This file |
| 17 | +``` |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## Architecture Principles |
| 22 | + |
| 23 | +### Module Organization (Flat Structure) |
| 24 | +All modules are `.rs` files in `src/`, no nested folders: |
| 25 | + |
| 26 | +```rust |
| 27 | +// src/main.rs |
| 28 | +mod cli; |
| 29 | +mod extract; |
| 30 | +mod github; |
| 31 | +mod install; |
| 32 | +mod platform; |
| 33 | +mod registry; |
| 34 | +mod util; |
| 35 | +``` |
| 36 | + |
| 37 | +**Why flat?** Simpler imports, easier navigation, scales well for CLI size. |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## Testing Strategy |
| 42 | + |
| 43 | +### Test Location |
| 44 | +**Integration tests ONLY** — Place all tests in `tests/` folder, not inline: |
| 45 | + |
| 46 | +``` |
| 47 | +tests/ |
| 48 | +├── extract.rs # Tests src/extract.rs public API |
| 49 | +├── github.rs # Tests src/github.rs public API |
| 50 | +├── platform.rs # Tests src/platform.rs public API |
| 51 | +├── registry.rs # Tests src/registry.rs public API |
| 52 | +└── error_handling.rs # Cross-module error tests |
| 53 | +``` |
| 54 | + |
| 55 | +### Test Requirements |
| 56 | +- Target **80%+ coverage** |
| 57 | +- Test public API only (don't test internals) |
| 58 | +- Use descriptive test names: `test_<function>_<scenario>` |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +## CI/CD Structure |
| 63 | + |
| 64 | +### Reusable Workflows |
| 65 | +Split CI into focused workflows with dependency chain: |
| 66 | + |
| 67 | +**Flow:** `Verify → Test → Build` |
| 68 | + |
| 69 | +| Workflow | Jobs | Purpose | |
| 70 | +|----------|------|---------| |
| 71 | +| `verify.yml` | `format`, `clippy` | Code quality gates | |
| 72 | +| `test.yml` | `linux`, `macos`, `windows` | Cross-platform tests | |
| 73 | +| `build.yml` | `linux`, `macos`, `windows` | Release binaries | |
| 74 | +| `main.yml` | Orchestrator | Chains workflows with `needs:` | |
| 75 | + |
| 76 | +### Platform Strategy |
| 77 | +- **Linux**: Use `rust:1.75-slim` container (faster, lighter) |
| 78 | +- **macOS/Windows**: Use `dtolnay/rust-toolchain` (no containers available) |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Code Style |
| 83 | + |
| 84 | +### Minimal Comments |
| 85 | +Only comment when: |
| 86 | +- Logic is complex/non-obvious |
| 87 | +- External dependencies behave unexpectedly |
| 88 | +- Workarounds exist for known issues |
| 89 | + |
| 90 | +**Avoid**: Obvious comments, "what" comments, redundant docstrings on private items. |
| 91 | + |
| 92 | +### Error Handling |
| 93 | +- Use `thiserror` for custom error types |
| 94 | +- Propagate with `?` operator |
| 95 | +- Add context with `.context()` from `anyhow` |
| 96 | +- **NO `unwrap()` in production code** |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Git Workflow |
| 101 | + |
| 102 | +### Branch Naming |
| 103 | +- `feature/description` — new features |
| 104 | +- `fix/description` — bug fixes |
| 105 | +- `refactor/description` — code restructuring |
| 106 | +- `docs/description` — documentation |
| 107 | + |
| 108 | +### Commits |
| 109 | +Follow conventional commits: |
| 110 | +``` |
| 111 | +<type>: <description> |
| 112 | +
|
| 113 | +<body explaining why, not what> |
| 114 | +``` |
| 115 | + |
| 116 | +Types: `feat`, `fix`, `refactor`, `docs`, `chore`, `test` |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +## Dependencies |
| 121 | + |
| 122 | +### Adding Dependencies |
| 123 | +1. Prefer crates.io over git repos |
| 124 | +2. Pin major versions: `crate = "1"` not `"1.2.3"` |
| 125 | +3. Group related deps (e.g., `tokio = { features = ["full"] }`) |
| 126 | + |
| 127 | +### Updating Dependencies |
| 128 | +- Run `cargo update` periodically |
| 129 | +- Check for security advisories with `cargo audit` |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +## Documentation |
| 134 | + |
| 135 | +### README.md |
| 136 | +Keep updated with: |
| 137 | +- Installation instructions |
| 138 | +- Basic usage examples |
| 139 | +- Platform support matrix |
| 140 | +- Configuration options |
| 141 | + |
| 142 | +### Code Documentation |
| 143 | +- Public API: Doc comments (`///`) |
| 144 | +- Complex logic: Inline comments (`//`) |
| 145 | +- Modules: Module-level docs (`//!`) |
| 146 | + |
| 147 | +--- |
| 148 | + |
| 149 | +## Performance Guidelines |
| 150 | + |
| 151 | +### CI Optimization |
| 152 | +- Use containers for Linux jobs (cached, faster) |
| 153 | +- Parallelize independent jobs |
| 154 | +- Cache `target/` between runs |
| 155 | + |
| 156 | +### Binary Size |
| 157 | +- Enable LTO in release: `lto = true` |
| 158 | +- Strip symbols: `strip = true` |
| 159 | +- Use `cargo bloat` to analyze |
| 160 | + |
| 161 | +--- |
| 162 | + |
| 163 | +## Security |
| 164 | + |
| 165 | +### Secrets |
| 166 | +- Use `GITHUB_TOKEN` for API access |
| 167 | +- Never commit `.env` files |
| 168 | +- Store tokens in repository secrets, not code |
| 169 | + |
| 170 | +### Dependencies |
| 171 | +- Run `cargo audit` before releases |
| 172 | +- Pin transitive deps if vulnerable |
| 173 | + |
| 174 | +--- |
| 175 | + |
| 176 | +## Release Process |
| 177 | + |
| 178 | +1. Update `CHANGELOG.md` |
| 179 | +2. Bump version in `Cargo.toml` |
| 180 | +3. Tag: `git tag v1.0.0` |
| 181 | +4. Push tag: `git push origin v1.0.0` |
| 182 | +5. CI builds release binaries automatically |
| 183 | +6. Create GitHub release with artifacts |
| 184 | + |
| 185 | +--- |
| 186 | + |
| 187 | +## Common Patterns |
| 188 | + |
| 189 | +### Adding a New Command |
| 190 | +1. Add variant to `cli.rs` (`Commands` enum) |
| 191 | +2. Implement handler in `src/<module>.rs` |
| 192 | +3. Wire in `main.rs` match statement |
| 193 | +4. Add tests in `tests/<module>.rs` |
| 194 | + |
| 195 | +### Error Propagation |
| 196 | +```rust |
| 197 | +// Good: Context + specific error |
| 198 | +let file = fs::read(&path) |
| 199 | + .context(format!("Failed to read {}", path.display()))?; |
| 200 | + |
| 201 | +// Bad: Generic error |
| 202 | +let file = fs::read(&path)?; // Less helpful |
| 203 | +``` |
| 204 | + |
| 205 | +--- |
| 206 | + |
| 207 | +## Resources |
| 208 | + |
| 209 | +- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/) |
| 210 | +- [Conventional Commits](https://www.conventionalcommits.org/) |
| 211 | +- [GitHub Actions Docs](https://docs.github.com/en/actions) |
| 212 | + |
| 213 | +--- |
| 214 | + |
| 215 | +*Last updated: 2026-04-21* |
0 commit comments