diff --git a/AGENTS.md b/AGENTS.md index 04fcb22..265a6c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,9 +1,104 @@ -## Role +# AGENTS.md -Write code like a Go Senior Developer. -Use the best practices, write modern idiomatic code, and handle all errors. -Keep an eye on security. +This file provides guidance to LLM agents when working with code in this repository. -## Context +## Project Overview -- go 1.25.5 \ No newline at end of file +Trackers is a Go application that aggregates torrent tracker links from multiple sources (HTTP, HTTPS, and local files). It: +- Polls configured sources at regular intervals +- Deduplicates and validates tracker links +- Caches results to disk for resilience +- Serves aggregated tracker lists via HTTP API +- Runs a single HTTP server with minimal dependencies + +This is an educational project written in Go 1.25.5. + +## Development Commands + +### Build +```bash +go build -o trackers ./main.go +``` + +### Run +```bash +go run main.go -config config.toml +``` + +### Test +The codebase has no tests currently. Tests can be added with: +```bash +go test ./... +``` + +To run a single test: +```bash +go test -run TestName +``` + +### Lint +```bash +go fmt ./... +go vet ./... +``` + +### Release Build +Uses goreleaser for cross-platform builds (Linux amd64/arm64): +```bash +goreleaser build --snapshot --clean +``` + +## Architecture + +**Single File Design**: All code is in `main.go` with clear functional separation: + +1. **Config System** (`loadConfig`): Parses TOML configuration with defaults + - `port`: HTTP server port (default: 8080) + - `cache_dir`: Directory for caching tracker lists (default: cache/) + - `poll_interval`: How often to refresh sources (default: 60m) + - `sources`: Array of URLs/file paths to fetch tracker lists from + +2. **Aggregator** (type `Aggregator`): Thread-safe in-memory deduplication + - Maintains per-source tracker sets using `sync.RWMutex` + - `Update()`: Stores new tracker list for a source + - `List()`: Returns combined sorted list across all sources + +3. **Polling System** (`pollSource`/`runOnce`): Background goroutine per source + - Fetches source on startup and at configured intervals + - Updates aggregator and writes to cache on success + - Graceful shutdown on SIGINT/SIGTERM + +4. **HTTP Handler** (`/list` endpoint): Returns deduplicated tracker list as plain text + - Links separated by double newlines + - Read timeouts enforce reasonable request handling + +5. **Source Fetching** (`fetchSource`): Pluggable source handlers + - **HTTP/HTTPS**: Makes requests with context support and timeout (15s) + - **File**: Reads local files via `file://` URLs + - Response is parsed line-by-line + +6. **Link Validation** (`normalizeLinks`/`isValidTrackerLink`): + - Strips whitespace and empty lines + - Validates URL format and supported schemes: `http`, `https`, `udp`, `ws`, `wss` + - Deduplicates via map-based set + +7. **Caching** (`writeCache`/`loadCachedLinks`): SHA1-hashed filenames in `cache_dir/` + - Enables graceful degradation if source becomes unavailable + - Filenames are hex-encoded SHA1(source_url) + ".txt" + +## Key Design Decisions + +- **No external dependencies except go-toml**: Keeps binary small and build simple +- **Simple HTTP server**: Uses stdlib `net/http` instead of frameworks +- **Per-source goroutines**: Allows independent polling without blocking +- **RWMutex for reads**: Readers don't block each other when listing trackers +- **Context propagation**: Respects shutdown signals in all async operations +- **Line-based parsing**: Flexible input format (handles various tracker list formats) + +## Testing Notes + +The project follows Go conventions but has no test files. Consider adding tests for: +- Link validation edge cases +- Config parsing with invalid inputs +- Concurrent aggregator updates +- Cache file I/O \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..36ebd67 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +# CLAUDE.md + +@AGENTS.md + +