This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
ShitPostr is a meme search and management app with semantic search. Built for homelab self-hosting.
Philosophy: Single-file architecture. All backend logic in index.ts, all frontend in index.html. Keep it simple.
bun install # Install dependencies
bun run dev # Development with hot reload
bun run start # Production
docker compose up # Full stack with PostgreSQL| File | Purpose |
|---|---|
index.ts |
All backend: Hono server, API routes, DB, Ollama, embeddings, scanner |
index.html |
All frontend: vanilla JS/CSS, grid, modals, meme editor |
schema.sql |
PostgreSQL + pgvector schema |
docker-compose.yml |
App + PostgreSQL containers |
- Static files:
/images/*route maps to/data/*directories (configured viaSTATIC_DIRS) - Search: Hybrid approach combining vector similarity + filename regex matching
- Embeddings: Generated client-side with Xenova transformers, stored as pgvector
- Frontend state: Global variables (
memes,currentMeme,filters), vanilla JS DOM manipulation - URL helper:
filePathToUrl()converts DB paths to serving URLs
- Runtime: Bun
- Server: Hono
- Database: PostgreSQL 17 + pgvector
- Embeddings: Xenova all-MiniLM-L6-v2 (384-dim vectors)
- Vision AI: Ollama llava:7b (optional)
- Frontend: Vanilla JS
GET / HTML page
GET /images/* Static image files (maps to /data/*)
GET /health Health check
GET /api/version App version from package.json
GET /api/memes List memes (filters: status, starred)
GET /api/memes/:id Single meme
PATCH /api/memes/:id Update meme
DELETE /api/memes/:id Delete meme
POST /api/memes/:id/star Toggle star
POST /api/memes/:id/generate Generate description
GET /api/search Search (params: q, mode=vector|text)
GET /api/stats Meme counts by status
GET /api/ollama-status Check Ollama availability
POST /api/upload Upload images
POST /api/scan Scan directory for images
GET /api/scan/status Scan progress
POST /api/generate-pending Batch generate descriptions
POST /api/cleanup Remove entries with missing files
POST /api/reset-processing Reset stuck processing to pending
POST /api/reset-errors Reset errors to pending
APP_NAME=ShitPostr # custom app name for branding
DATABASE_URL=postgres://postgres:postgres@localhost:5432/shitpostr
OLLAMA_URL=http://localhost:11434
OLLAMA_MODEL=llava:7b
UPLOAD_DIR=/data/memes/uploads
PORT=3000
STATIC_DIRS=/data/memes # comma-separated for multiple
ZIPLINE_URL=https://your-zipline.com # optional
ZIPLINE_TOKEN=your-token # optional# Download imgflip templates
./scripts/download-imgflip-api.sh /data/memes/imgflip-templates
# Scan directory
curl -X POST http://localhost:3000/api/scan \
-H 'Content-Type: application/json' \
-d '{"directory": "/data/memes"}'docker compose up -d
docker ps | grep shitpostr
docker logs -f shitpostrUse tea for Gitea operations. Auto-detects repo from git remotes.
# PRs
tea pr list # List open PRs
tea pr <number> # Show PR details
tea pulls <number> --comments # Show PR with comments
tea pr create --title "..." --description "..."
tea pr checkout <number> # Checkout PR locally
tea pr merge <number>
tea pr approve <number> # Approve PR
tea pr reject <number> # Request changes
# Issues
tea issue list
tea issue <number> # Show issue details
tea issue create --title "..." --body "..."
tea comment <issue-number> "text"
# Repo
tea repo # Current repo info
tea clone owner/repo
tea open # Open in browser
# Account
tea whoami
tea login add # Configure Gitea instance
tea notificationsOptions: --login <name> for multi-server, --repo owner/repo to target specific repo, --output simple|csv|json for scripts.