# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview LinkBeam is a static site generator for creating personal link-in-bio pages (similar to Linktree). It reads a YAML configuration file containing user profile information, links, and social media, then generates a themed HTML page using Go templates. ## CI/CD Pipeline The project uses Gitea Actions for continuous integration and deployment. ### Workflows 1. **CI Pipeline** (`.gitea/workflows/ci.yml`): - Runs on push to main/develop and pull requests - **Lint**: golangci-lint, go fmt, go vet - **Test**: Run tests with race detection and coverage - **Build**: Multi-platform builds (Linux, Windows, macOS) for amd64, 386, arm64, armv7 - **Docker**: Build multi-arch Docker images 2. **Docker Publish** (`.gitea/workflows/docker-publish.yml`): - Triggered on version tags (v*) - Builds and pushes Docker images to container registry - Multi-architecture: linux/amd64, linux/arm64, linux/arm/v7 3. **Release** (`.gitea/workflows/release.yml`): - Triggered on semver tags (v*.*.*) - Creates GitHub/Gitea releases with binaries for all platforms - Generates SHA256 checksums for verification ### Local Testing ```bash # Check version ./linkbeam -v # or: ./linkbeam --version # Test Docker build docker build -t linkbeam:test . # Run Docker container docker run -v $(pwd)/config.yaml:/app/config/config.yaml \ -v $(pwd)/dist:/app/dist \ linkbeam:test # Test with docker-compose docker-compose up ``` ## Development Commands ### Pre-commit Setup This project uses pre-commit hooks for code quality. First-time setup: ```bash # Install pre-commit hooks make install-hooks # or: pre-commit install # Run all hooks manually make pre-commit # or: pre-commit run --all-files ``` The hooks automatically run on commit and check: `go fmt`, `goimports`, `go vet`, `golangci-lint`, `go test`, `go mod tidy`, YAML syntax, and more. ### Building and Running ```bash # Build binary (outputs to dist/linkbeam) make build # or: go build -o dist/linkbeam cmd/linkbeam/main.go # Run with example config make run-example # or: go run cmd/linkbeam/main.go --config internal/config/testdata/config.yaml # Run with custom config (long flags) ./linkbeam --config config.yaml --template templates/base.html --output dist/index.html # Run with custom config (short flags) ./linkbeam -c config.yaml -t templates/base.html -o dist/index.html # Run all tests make test # or: go test -v ./... # Run tests for a specific package go test ./internal/config go test ./internal/generator # Run a single test function go test -v -run TestLoad ./internal/config # Clean build artifacts make clean ``` ### CLI Options - `-c, --config`: Path to config YAML file (default: "config.yaml") - `-t, --template`: Path to HTML template (default: "templates/base.html") - `-o, --output`: Path to output HTML file (default: "dist/index.html") - `-v, --version`: Print version information ### Output The `dist/` directory contains both build artifacts and generated site: - `dist/linkbeam` - Compiled binary - `dist/index.html` - Main HTML page - `dist/themes/` - Copied CSS theme files ## Architecture ### Two-Layer Structure 1. **Config Layer** (`internal/config/`): - Loads and validates YAML configuration files - Defines data structures: `Config`, `Link`, `Social` - Validates theme (must be "light" or "dark") and required fields (name cannot be empty) - Config validation happens automatically during `config.Load()` 2. **Generator Layer** (`internal/generator/`): - **HTML Generation**: Orchestrates template rendering using Go's `html/template` - `GenerateSite(cfg, templatePath, outPath)` - Creates HTML from templates - **Asset Management**: Copies CSS themes and static files to output directory - `CopyAssets(distDir, themeDirs...)` - Copies theme files to dist/themes/ - **Text Rendering**: Plain-text representation for debugging - `RenderUserPage(cfg)` - Returns text-based preview of the page ### Configuration Format The config YAML structure in `internal/config/testdata/config.yaml`: - `name`: User's display name (required) - `bio`: Short biography text - `avatar`: Path to avatar image - `theme`: "light" or "dark" (validated) - `links[]`: Array of link objects with `title`, `url`, `icon` - `socials[]`: Array of social media links with `platform`, `url`, `icon` ### Templates Templates in `templates/` use Go template syntax: - `base.html`: Main page template with theme support (`data-theme="{{ .Theme }}"`) - Template receives the entire `Config` struct as data - Access config fields with `{{ .Name }}`, `{{ .Bio }}`, etc. - Iterate over links with `{{- range .Links }}` ### Testing Strategy - Tests use table-driven patterns and dependency injection - `cmd/linkbeam/main_test.go`: Mocks the config loader and captures stdout - Config tests validate YAML parsing and business rules - Generator tests verify file creation and template execution - All tests use the testdata in `internal/config/testdata/config.yaml`