# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Build and Test Commands ```bash # Build library packages go build ./pkg/... # Build CLI tool go build ./cmd/... # Run all tests go test ./... # Run tests for a specific package go test ./pkg/toughswitch/... -run TestClient_AddDel # Tidy module dependencies go mod tidy ``` ## Architecture This repository provides Go client libraries for interacting with Ubiquiti network devices via reverse-engineered REST APIs, plus a CLI tool. ### Package Structure - `pkg/toughswitch/` - Client for ToughSwitch devices (e.g., TS-8-PRO) - `pkg/edgeos/` - Client for EdgeOS devices (EdgeRouter, EdgeSwitch) - `cmd/` - CLI tool using cobra ### Library Client Design Pattern Both `pkg/toughswitch` and `pkg/edgeos` follow the same multi-device client pattern: 1. **Client** - Top-level struct holding a map of `deviceClient` instances keyed by host 2. **deviceClient** - Per-device HTTP client with authentication state (token for ToughSwitch, cookies for EdgeOS) 3. **Config** - Device connection settings (host, credentials, TLS options, timeout) Key characteristics: - Thread-safe: Uses `sync.RWMutex` for device map access and `sync.Mutex` for per-device operations - Auto-login: Automatically authenticates on 401 responses and retries the request - Explicit login: `Login(ctx, host)` can be called to pre-authenticate - Concurrent multi-device: `GetAll*` methods use `sync.WaitGroup.Go()` for parallel queries API pattern for each package: - `MustNew(ctx, []Config)` - Constructor that accepts multiple device configs - `Login(ctx, host)` - Explicit authentication (also happens automatically on 401) - `Add(cfg)` / `Del(host)` - Dynamic device management - `Get(ctx, host)` - Single device query - `GetAll(ctx)` - Parallel query across all devices, returns `map[string]*Resource` ### CLI Architecture (`cmd/`) The CLI uses cobra with a prerun chain pattern: - `cmd/cmd/root.go` - Root command with `PersistentPreRunE` hook - `cmd/cmd/prerun.go` - Prerun functions executed in order: `validateConfigFile` → `prepareConfig` → `prepareLogger` → `setEnvironment` → `prepareClients` - `cmd/cmd/client.go` - Shared `fetchDevice()` helper that retrieves clients from context - `cmd/internal/util/context.go` - Context helpers for config, logger, and clients - `cmd/internal/config/config.go` - Config loading from YAML/JSON files with env overlay Context flow: Prerun creates clients based on config and stores them in context. Commands retrieve clients via `util.ToughSwitchClientFromContext(ctx)` / `util.EdgeOSClientFromContext(ctx)`. ### Authentication - **ToughSwitch**: Token-based via `x-auth-token` header from `/api/v1.0/user/login` - **EdgeOS**: Cookie-based from `/api/login2` endpoint ### Testing Tests use `mockTransport` implementing `http.RoundTripper` to mock HTTP responses without network calls.