Files
William Valentin 3434db3c59 feat: complete agent monitoring - hook, UI, and backend filter
- Add event_type and framework filters to events query endpoint
- Add /agents SPA route to web-ui server
- Add Agents nav link and route in frontend
- Add agents page CSS (timeline, VM pills, stats panel)
- Build VM status strip, activity timeline, and real-time stats
- Add agentmon hook for OpenClaw (HOOK.md + handler.ts)
- Add docker-compose, Dockerfile, and supporting infra files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 00:26:42 -07:00

167 lines
4.8 KiB
Markdown

# AGENTS.md
This file provides guidelines for agentic coding agents working on the agentmon repository.
## Build/Lint/Test Commands
```bash
# Run all tests
go test ./...
# Run tests for a specific package
go test ./internal/event
# Run a single test
go test ./internal/event -run TestValidate_ValidEvent
# Run tests with verbose output
go test -v ./...
# Tidy dependencies
go mod tidy
# Run services via Makefile
make tidy
make test
make run-ingest # Ingest gateway (requires NATS_URL, NATS_TOPIC)
make run-query # Query API (requires DATABASE_URL)
make run-ui # Web UI
make run-processor # Event processor (requires DATABASE_URL, NATS_URL, NATS_TOPIC)
# Build executables
go build -o ingest-gateway ./cmd/ingest-gateway
go build -o query-api ./cmd/query-api
go build -o web-ui ./cmd/web-ui
```
## Code Style Guidelines
### Imports
- Order: stdlib, internal packages, external packages
- Group by blank line between each section
- No unused imports
Example:
```go
import (
"context"
"database/sql"
"agentmon/internal/event"
"agentmon/internal/httpx"
"github.com/go-chi/chi/v5"
"github.com/jackc/pgx/v5"
)
```
### Formatting
- Use `go fmt` or enable auto-formatting
- Standard Go formatting rules apply
- No inline comments unless necessary
### Types
- Use `any` for generic types (not `interface{}`)
- Use pointer types (`*int64`) for optional JSON fields
- Struct tags for JSON serialization: `json:"field_name,omitempty"`
- Use `sql.ErrNoRows` for "not found" database errors
### Naming Conventions
- Exported: CamelCase (e.g., `ValidationError`, `Publish`)
- Unexported: camelCase (e.g., `db`, `validate`)
- Acronyms: keep uppercase (e.g., `DB`, `NATS`, `URL`)
- Constants: CamelCase (e.g., `validTypes`)
- Test functions: `Test<Function>_<Scenario>`
### Error Handling
- Always check errors, don't ignore
- Use `log.Fatalf` for startup errors (main package only)
- Use `errors.As()` for type assertions: `errors.As(err, &ve)`
- Custom error types must implement `Error() string` method
- Return errors from functions, handle at call site
- HTTP errors: return JSON with error field, appropriate status code
Example:
```go
if err != nil {
return nil, fmt.Errorf("operation failed: %w", err)
}
if ve, ok := err.(ValidationError); ok {
return ValidationError{Field: "field", Message: "message"}
}
```
### Database
- Use `context.Context` for all DB operations
- Use pgx/v5 via stdlib interface: `sql.Open("pgx", url)`
- Check `sql.ErrNoRows` explicitly for not-found cases
- Always defer `db.Close()` in main functions
### HTTP
- Use chi router with middleware
- Standard middleware chain: `RequestID`, `RealIP`, `Logger`, `Recoverer`
- Health check endpoint: `GET /healthz` returns 200 with "ok"
- JSON responses: use `httpx.WriteJSON(w, status, data)`
- Get path params: `chi.URLParam(r, "paramName")`
- Get query params: `r.URL.Query().Get("key")`
### Configuration
- Use environment variables for configuration
- Helper pattern: `envDefault(key, defaultValue)` function
- Required env vars: log.Fatal if missing
- Optional env vars: provide sensible defaults
### Validation
- Validate all input (HTTP, events)
- Return structured errors with field path and message
- Type assertion with comma-ok for error type checking
- Valid event types: `session.start`, `session.end`, `run.start`, `run.end`, `span.start`, `span.end`, `error`, `metric.snapshot`
### Testing
- Use standard `testing` package
- Test file naming: `*_test.go`
- Test function naming: `Test<Function>_<Scenario>`
- Use `t.Fatalf` for setup failures
- Use `t.Fatal` for assertion failures (not `t.Error`)
- Minimal test structure: setup, act, assert
Example:
```go
func TestValidate_ValidEvent(t *testing.T) {
raw := `{"schema": {"name": "agentmon.event", "version": 1}}`
var m map[string]any
_ = json.Unmarshal([]byte(raw), &m)
err := Validate(m)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
}
```
### Context Usage
- Pass `context.Context` to functions that do I/O or external calls
- Use `context.WithTimeout` for operations with deadlines
- Defer cancel functions
- Example: `ctx, cancel := context.WithTimeout(ctx, 5*time.Second)`
### Package Structure
- `cmd/`: Executable entry points (main packages)
- `internal/`: Internal packages not imported by external code
- `internal/event/`: Event schema and validation
- `internal/httpx/`: HTTP utilities
- `internal/store/postgres/`: Database operations
- `internal/queue/nats/`: NATS publishing
### JSON Handling
- Decode to `map[string]any` for flexible event processing
- Type assertions: `if v, ok := m["key"].(string); ok {}`
- Use `json.RawMessage` for buffering JSON data
- JSON encoder/decoder for I/O
### Logging
- Use `log.Printf` for general logging
- Use `log.Fatalf` for unrecoverable errors in main
- Minimal logging in packages (prefer returning errors)