From 64116ce3daa9fb943bf224f84435740db3ad9683 Mon Sep 17 00:00:00 2001 From: TwiN Date: Fri, 3 Apr 2026 13:48:31 -0400 Subject: [PATCH] docs(ai): Add AGENTS.md --- .github/copilot-instructions.md | 1 + .../workflows/regenerate-static-assets.yml | 2 +- .github/workflows/test-ui.yml | 2 +- AGENTS.md | 84 +++++++++++++++++++ Makefile | 10 ++- 5 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..b90d8590 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +See AGENTS.md for agent instructions \ No newline at end of file diff --git a/.github/workflows/regenerate-static-assets.yml b/.github/workflows/regenerate-static-assets.yml index b6052604..486b8bbc 100644 --- a/.github/workflows/regenerate-static-assets.yml +++ b/.github/workflows/regenerate-static-assets.yml @@ -52,7 +52,7 @@ jobs: ref: ${{ steps.pr.outputs.ref }} - name: Regenerate static assets run: | - make frontend-install-dependencies + make frontend-install make frontend-build - name: Commit and push changes id: commit diff --git a/.github/workflows/test-ui.yml b/.github/workflows/test-ui.yml index 8cb1fd23..9756d7d5 100644 --- a/.github/workflows/test-ui.yml +++ b/.github/workflows/test-ui.yml @@ -14,5 +14,5 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v5 - - run: make frontend-install-dependencies + - run: make frontend-install - run: make frontend-build \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..ffac147e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,84 @@ +# AGENTS.md + +Guidance for AI coding agents working in this repository. + +## Commands + +- `make install` — Build the `gatus` binary +- `make run` — Run in dev mode (uses `./config.yaml`) +- `make test` — Run all Go tests with coverage +- `make clean` — Remove built binary +- `make frontend-install` — Install frontend npm dependencies +- `make frontend-build` — Build the Vue.js frontend (**must run after any `web/` changes**) +- `make frontend-dev` — Start the Vue dev server + +## Key Rules + +- **Vendored dependencies**: After adding/updating a Go dependency, run `go mod tidy && go mod vendor` +- **Frontend build artifacts**: `web/static/` is generated by `make frontend-build` and embedded into the Go binary at compile time via `//go:embed`. Never edit files in `web/static/` directly +- **Config validation order**: In `config/config.go` `parseAndValidateConfigBytes`, `ValidateAlertingConfig` **must** run before `ValidateEndpointsConfig` because provider default alerts must be parsed before endpoint defaults are set +- **Invalid configs panic at startup** — validation errors are fatal, not graceful +- **Hot-reload**: `main.go` watches the config file and re-runs the full stop → save → load → init → start cycle. New startup logic must account for this + +## Environment Variables + +- `GATUS_CONFIG_PATH` — Config file path (default: `config/config.yaml`); can be a directory of YAML files (deep-merged) +- `GATUS_LOG_LEVEL` — `DEBUG`, `INFO`, `WARN`, `ERROR` +- `ENVIRONMENT=dev` — Enables CORS for frontend dev on `localhost:8081` + +## Project Structure + +- `main.go` — Entry point; loads config, initializes storage, starts watchdog + API server +- `config/` — Central config struct (`config.go`) and sub-packages per config section (each with `ValidateAndSetDefaults()`) +- `alerting/` — Alerting config (`config.go`), alert types (`alert/type.go`), and one sub-package per provider under `provider/` +- `api/` — Fiber-based HTTP API routes and SPA serving +- `watchdog/` — Monitoring loop; spawns a goroutine per endpoint with semaphore-based concurrency control +- `client/` — HTTP/gRPC client used for health checks +- `storage/store/` — Storage abstraction with `memory/`, `sql/` (SQLite + PostgreSQL) implementations +- `security/` — Authentication (basic + OIDC) and security middleware +- `web/app/` — Vue 3 frontend source; builds to `web/static/` (embedded into the Go binary) +- `vendor/` — Vendored Go dependencies (committed to repo) + +## Common Changes + +### Adding an Alerting Provider + +Use `alerting/provider/slack/` as the reference implementation. Every new provider touches **6 locations**: + +1. **Create provider package** — `alerting/provider/{name}/{name}.go` + `{name}_test.go` + - `Config` struct with `Validate()` and `Merge(*Config)` methods + - `AlertProvider` struct with `DefaultConfig` (yaml inline), `DefaultAlert *alert.Alert`, `Overrides []Override` + - Use `client.GetHTTPClient(nil)` (not `http.DefaultClient`), always `defer response.Body.Close()` +2. **Register type** — Add `Type{Name} Type = "{name}"` in `alerting/alert/type.go` +3. **Add to config struct** — Add field to `alerting.Config` in `alerting/config.go`; the **YAML tag must exactly match** the `alert.Type` string (reflection-based lookup via `GetAlertingProviderByAlertType`) +4. **Add compile-time checks** — Both `_ AlertProvider = (*pkg.AlertProvider)(nil)` **and** `_ Config[pkg.Config] = (*pkg.Config)(nil)` in `alerting/provider/provider.go` +5. **Register in validation** — Add the type to the `alertTypes` slice in `config/config.go` `ValidateAlertingConfig` +6. **Document** — Add to README.md in alphabetical order + +### Adding a Config Section + +1. Create package in `config/` with struct + `ValidateAndSetDefaults()` method +2. Add field to `Config` struct in `config/config.go` +3. Add `Validate*` call in `parseAndValidateConfigBytes` — **respect ordering constraints** (see comments in that function) + +## Frontend + +- Vue 3 Composition API (`