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

7.2 KiB

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.