Files
air/AGENTS.md
2026-05-19 22:02:51 +08:00

164 lines
7.2 KiB
Markdown

# AGENTS
Guidelines for contributors and AI coding agents working in this repository.
## Goals
- Keep changes minimal, focused, and idiomatic to Go.
- When adding changes, do NOT break existing behavior.
- Make changes small and easy to review.
- Code and comments must be written in English.
- Prefer root-cause fixes over band-aids; do not refactor unrelated code.
- Maintain user-facing behavior and CLI flags unless explicitly changing them.
## Project Snapshot
- Language: Go (modules enabled; `go 1.25` in `go.mod`).
- Module path: `github.com/air-verse/air`.
- Entry: `main.go`.
- Core package: `runner/` (watcher, engine, flags, config, proxy).
- Docs: `README*.md`, `air_example.toml`, `docs/`.
- Tooling: `Makefile`, `hack/check.sh`, `hooks/pre-commit`, `.golangci.yml`.
- Default config file: `.air.toml` (generated by `air init`).
## Repository Layout
- `main.go`: CLI entrypoint and flag parsing.
- `runner/engine.go`: build/run loop and watcher orchestration.
- `runner/config.go`: config schema, defaults, parsing, validation.
- `runner/flag.go`: CLI flag wiring.
- `runner/watcher.go`: fsnotify vs polling watcher selection.
- `runner/proxy*.go`: live-reload proxy, SSE stream, embedded JS.
- `runner/util*.go`: platform helpers, process control, misc utilities.
- `runner/*_test.go`: unit tests and platform-specific tests.
- `hack/check.sh`: goimports + golangci-lint driver.
- `hooks/pre-commit`: runs `hack/check.sh` on staged files.
## Build / Lint / Test
- Install tools + hook: `make init` (goimports + golangci-lint v2.6.1).
- Format + lint staged Go files: `make check`.
- Format + lint all Go files: `make check scope=all`.
- Build binary: `make build` (runs `make check` first).
- Install locally: `make install` (runs `make check` first).
- CI prep (module tidy): `make ci`.
- Full test suite: `go test ./...` or `make test` (race + timeout).
- CI tests: `make test-ci` (CI=true, longer timeout).
- Pre-commit hook: runs `./hack/check.sh` on staged files.
### Single Test Recipes
- Single package: `go test ./runner -v`.
- Single test: `go test ./runner -run '^TestName$' -count=1 -v`.
- Subtest: `go test ./runner -run '^TestName$/Subcase$' -count=1`.
- All packages, one test: `go test ./... -run '^TestName$' -count=1`.
- Add `-race` or `-timeout=3m` when debugging flakiness.
## Code Style (Go)
- Formatting: run `goimports` (it also applies `gofmt`).
- Imports: let `goimports` group stdlib, third-party, local imports.
- Naming: `CamelCase` for exported, `lowerCamel` for unexported.
- Initialisms: use standard forms (ID, URL, HTTP, JSON).
- Receivers: keep receiver names short and consistent (`cfg`, `e`, `p`).
- Types: prefer concrete types over `any`; avoid needless interfaces.
- Constants: use `const` for defaults; use `0o755` style perms.
- Zero values: design structs so zero values are valid when possible.
- Early returns: avoid deeply nested `else` blocks.
- Paths: use `filepath` for OS-safe path handling.
- Shelling out: prefer `exec.Command` with args; use `/bin/sh -c` only when needed.
- Platform code: maintain `*_linux.go`, `*_windows.go`, build tags parity.
- Comments: keep short, English, and explain "why" more than "what".
- Use `time.Duration` for timeouts and backoffs.
- Prefer value receivers unless mutation or large copies require pointers.
- Avoid globals except for constants and small immutable vars.
- Treat nil slices as empty; do not rely on non-nil defaults.
- Keep TOML/JSON tags aligned with field names and usage strings.
## Error Handling & Logging
- Wrap errors with context: `fmt.Errorf("read config: %w", err)`.
- Use `errors.Is/As` for comparisons, `errors.Join` for aggregates.
- Avoid panics in packages; `log.Fatal` only at CLI entrypoints.
- Log via `mainLog`, `buildLog`, `runnerLog`, `watcherLog` in `runner`.
- Keep log output concise and consistent with existing prefixes.
## Concurrency & State
- Guard shared state with `sync.Mutex` or `sync/atomic`.
- Avoid data races; keep goroutines bounded and cancellable.
- Use channels for signaling (see `buildRunCh` in `runner/engine.go`).
- Use `context` and timeouts for operations that may block on I/O.
## Tests
- Location: alongside code as `*_test.go`.
- Style: table-driven tests with `t.Run` where it improves clarity.
- Parallelism: use `t.Parallel()` only for isolated tests.
- Helpers: use `t.Helper`, `t.TempDir`, `t.Setenv`, `t.Cleanup`.
- Assertions: use `testify/require` for fatal checks, `testify/assert` for soft checks.
- Fixtures: prefer `_testdata` and temp dirs; avoid network dependencies.
- OS coverage: use `*_windows_test.go`, `*_linux_test.go` for platform behavior.
## Config / CLI Discipline
- Config fields: edit `runner/config.go`, update parsing/defaults/tests.
- CLI flags: update `runner/flag.go`, sync help text, update README usage.
- Keep `air_example.toml` aligned with any config changes.
- Behavior changes must include README updates and tests.
## Documentation
- Update `README.md` for user-visible changes (flags, config, examples).
- Keep `docs/` content accurate when behavior changes.
- Add concise migration notes for breaking or behavioral changes.
- Mention new environment variables or defaults in docs.
## Tooling and Linters
- `make check` runs `hack/check.sh` -> `goimports` + `golangci-lint`.
- Enabled linters include: `errcheck`, `revive`, `staticcheck`, `testifylint`, `unused`.
- Fix lint warnings rather than suppressing unless clearly justified.
- Keep changes compatible with the current Go version in `go.mod`.
## Scope and Safety
- Avoid touching `vendor/`, `third_party/`, or generated files.
- Do not change CLI output or flags unless explicitly requested.
- Avoid broad refactors; keep changes localized to the feature/bug.
- Prefer root-cause fixes over temporary workarounds.
- Do not add dependencies unless there is a clear, reviewed need.
- Assume offline mode; no external network usage.
## Cursor / Copilot Rules
- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` found.
- If any are added later, follow them and copy key points here.
## For AI Coding Agents (Codex CLI)
- For multi-step tasks, maintain an explicit plan and mark progress.
- Keep edits in a single focused patch per logical change.
- Briefly state what you are about to do before running commands.
- Prefer `rg` for searches and keep file reads to small chunks.
- Validate with `make check` and `go test ./...` when changes touch Go code.
- Avoid touching unrelated files; do not reformat the repo wholesale.
## Release Notes (maintainers)
- Follow the README "Release" section for tagging; CI performs builds.
## Review guidelines
- Review all code changes in this pull request against the style guide. Also check for possible bugs. Diffs are important, but read the full file for proper context. Make it clear that all suggestions are optional and the final decision belongs to the human reviewer.
- Only report real style guide violations. Do not complain about `else` statements when early returns are already used correctly. However, you may point out excessive nesting.
- Use simple and concise English. Keep sentences short and easy to understand.
- Only create comments for actual issues. If the code follows the guidelines and no issues are found, comment only: `lgtm`
---
Questions or uncertain scope? Open an issue or ask for clarification before implementing.