# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview mcdoc is a public documentation server for the Metacircular platform. It fetches markdown files from Gitea repositories, renders them to HTML, and serves a navigable read-only site. No authentication required. See `ARCHITECTURE.md` for the full specification. **Priorities (in order):** correctness, simplicity, readability. ## Build Commands ```bash make all # vet → lint → test → build make mcdoc # build binary with version injection make build # compile all packages make test # run all tests make vet # go vet make lint # golangci-lint make devserver # build and run locally with srv/mcdoc.toml make clean # remove built binaries make docker # build container image ``` Run a single test: ```bash go test ./internal/server -run TestDocPage ``` ## Tech Stack - **Language:** Go 1.25+, `CGO_ENABLED=0`, statically linked - **Module path:** `git.wntrmute.dev/kyle/mcdoc` - **Config:** TOML via `go-toml/v2`, env overrides via `MCDOC_*` - **HTTP:** chi router, htmx for navigation - **Rendering:** goldmark (GFM), chroma (syntax highlighting) - **Templates:** Go `html/template`, embedded via `//go:embed` - **Linting:** golangci-lint v2 ## Architecture - Single binary, single container - Fetches markdown from Gitea API (mc org, public repos) - Renders to HTML at fetch time, caches in memory - Refreshes via Gitea push webhooks + 15-minute poll fallback - mc-proxy terminates TLS, mcdoc serves plain HTTP - No database, no local state beyond config ## Package Structure - `cmd/mcdoc/` — CLI entry point (cobra: server subcommand) - `internal/config/` — TOML config loading - `internal/gitea/` — Gitea API client - `internal/cache/` — In-memory content cache - `internal/render/` — goldmark rendering pipeline - `internal/server/` — HTTP server, chi routes, htmx handlers - `web/` — Templates and static files, embedded via `//go:embed` ## Critical Rules - No authentication — this is a public site - Never serve stale-on-error without logging the staleness - Webhook secret must be validated (HMAC-SHA256) before processing - All user-supplied path segments must be sanitized (no path traversal) - Template rendering must use html/template (auto-escaping), never text/template - No CGo in production - Generated code is never edited by hand