# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Glimbus is a Go-based web service that processes images and videos using DeepDanbooru or Stable Diffusion WebUI for image tagging. The service accepts uploaded media files and returns tags by analyzing frames. **Core Architecture:** - Two-file Go web server (`main.go`, `video.go`) - Uses chi router with standard library net/http - Listens on `0.0.0.0:6679` - Accepts multipart file uploads via POST to `/` - For videos: extracts frames at variable intervals, sends each frame to upstream tagger, aggregates tags - For images: sends directly to upstream tagger - Supports two upstream runners (configured via env vars): - `DeepDanbooru` (via `DD_ADDRESS`) - `StableDiffusionWebUI` (via `SD_ADDRESS`) ## Build and Run Commands **Build:** ```bash go build -o glimbus . ``` **Run (development with logging):** ```bash # Set environment variables first (see .envrc for example) export LOG_LEVEL=debug # or RUST_LOG=debug for compatibility export SD_ADDRESS=http://your-server:port export SD_MODEL=vitv3 # or wd14-vit-v2-git (default) ./glimbus ``` **Run tests:** ```bash go test ./... ``` ## Environment Variables Required (one of): - `DD_ADDRESS`: DeepDanbooru server URL (checked first) - `SD_ADDRESS`: Stable Diffusion WebUI server URL Optional: - `SD_MODEL`: Model name for SD WebUI (default: `wd14-vit-v2-git`) - `LOG_LEVEL`: Log level (`debug` for verbose logging) - `RUST_LOG`: Also supported for compatibility (`debug` enables debug logging) ## Video Processing Logic The service adaptively samples video frames based on duration: look at `getFrameSkipSeconds` to find the mapping, but its kind of like this (as an example): - 0-10s: every 2 seconds - 11-60s: every 10 seconds - 61-120s: every 15 seconds - 121-300s: every 20 seconds - 301-1000s: every 30 seconds - 1001-1200s: every 40 seconds - 1201s+: every 60 seconds Frame extraction uses ffmpeg with fast seeking (`-ss` before input), extracting one frame per interval. All tags from all frames are collected into a deduplicated set. ## Key Implementation Details **Frame Rate Calculation** (video.go): The service attempts to get frame rate from stream metadata, falls back to calling ffprobe directly if the metadata returns 0/0. **Frame Count Calculation** (video.go): Tries stream metadata first, then format duration x frame rate, finally falls back to full decode with `ffprobe -count_frames`. **Upstream Runner Detection** (main.go): Checks `DD_ADDRESS` first, then `SD_ADDRESS`. Exits with error if neither is set. **Response Format:** - Returns JSON array of tags: `["tag1", "tag2", ...]` - On error: returns JSON string: `"error message"` ## Dependencies Core (Go standard library + chi): - `github.com/go-chi/chi/v5`: HTTP router - `net/http`: HTTP server - `os/exec`: ffmpeg/ffprobe execution - `encoding/json`: JSON serialization - `log/slog`: Structured logging External tools required: - `ffmpeg`: Frame extraction - `ffprobe`: Video metadata The service has an 8GB body size limit for file uploads.