Split embed.go with build tags so builds work without data files (embed_nodata.go provides empty fallbacks, embed_data.go embeds real data when built with -tags embed_data). Add Woodpecker CI pipeline (format/lint/build), release pipeline (goreleaser + Docker), Containerfile, docker-compose.yml, and goreleaser config. Update Makefile with format/lint targets and embed_data tag on build targets. Rename project from terraria-item-tree to terraria-companion throughout. Fix all errcheck lint warnings in fetcher.go and server.go. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
AGENTS.md - Terraria Companion
Project Summary
Go web application that fetches Terraria item/recipe/drop data from the Terraria Wiki and serves a frontend for searching items and visualizing crafting trees. Single binary with embedded assets, no external Go dependencies.
Tech Stack
- Backend: Go 1.24+ (standard library only, no external deps)
- Frontend: Vanilla HTML/CSS/JS (no framework)
- Data source: Terraria Wiki Cargo API (
terraria.wiki.gg/api.php) - Embedding:
//go:embedfor static assets and data files
Project Structure
main.go — CLI entry point (serve/fetch commands)
server.go — HTTP server, API endpoints, DataStore
fetcher.go — 4-phase wiki data pipeline (items→recipes→drops→icons)
embed.go — go:embed declarations
public/ — Frontend (index.html, style.css, script.js, icons/)
data/ — Fetched JSON data (items.json, recipes.json, drops.json, splashes.json)
Makefile — Build/dev/fetch targets
Build & Run
make build # Production binary with embedded assets
make dev # Development mode (hot-reload, serves from disk)
make fetch # Fetch data from wiki (resumable)
make clean # Remove binaries
Default port: 3000 (override with PORT env var).
Architecture
Server (server.go)
DataStore: Thread-safe (RWMutex) in-memory store with maps for items, recipes, drops- API routes:
/api/search,/api/item,/api/recipes,/api/drops,/api/status - Search ranking: exact match → prefix → contains (max 30 results)
- Dev mode (
DEV=1): pollsdata/*.jsonevery 5s for hot-reload - Production: serves from embedded filesystem
Fetcher (fetcher.go)
- 4 phases: items, recipes, drops, icons
- Resumable via
data/.fetch-state.json(safe to interrupt) - Rate limited: 400ms delay, exponential backoff on 429s
- Writes JSON arrays to
data/directory
Frontend (public/script.js)
- Client-side caching (itemCache, recipeCache, dropCache)
- 200ms debounced search
- Modal-based item detail with recursive crafting tree rendering
- Icon fallback: local
/icons/→ wiki URL
Key Conventions
- No external Go dependencies — standard library only
- No tests currently exist
- Data files in
data/and icons inpublic/icons/are gitignored - The compiled binary embeds all assets for single-file distribution
package.jsonis legacy from pre-Go version — not used
API Endpoints
| Endpoint | Params | Returns |
|---|---|---|
GET /api/search |
q (query string) |
Array of matching items (max 30) |
GET /api/item |
name (item name) |
Single item object or null |
GET /api/recipes |
name (item name) |
Array of recipes for item |
GET /api/drops |
name (item name) |
Array of drop sources |
GET /api/splashes |
— | Array of splash text strings |
GET /api/status |
— | Item/recipe/drop counts + fetch state |