A calm, ad-free visual inspiration platform built on the AT Protocol. Users save images into Collections.
| Directory | Language | Description |
|---|---|---|
appview/ |
Go | AT Protocol AppView — HTTP server with OAuth, TAP listener, backed by PostgreSQL + pgvector |
inference/ |
Python | FastAPI inference server — embeds images and text into a shared vector space (SigLIP2) |
The appview subscribes to a TAP WebSocket at startup to index is.currents.* records from the AT Protocol firehose into local collection and save tables. Saves are always written to the user's PDS first (via the browser extension or the appview's POST /resave endpoint for resaves), then indexed asynchronously by the TAP listener — the appview DB is never written to directly by HTTP handlers for user content.
SESSION_SECRET=<random-string> docker compose up --build- AppView: http://localhost:8080
- Inference: run separately (see
inference/)
./dev.sh starts everything — the dev compose stack (db/tap/appview/clustering),
the inference server, the frontend, and a cloudflared tunnel — each in its own
tmux window (docker, inference, frontend, tunnel).
./dev.sh # build + start everything, attach to tmux
./dev.sh stop # stop inference/frontend/tunnel (docker stack keeps running)
./dev.sh stop --down # also tear down the docker stack
./dev.sh attach # reattach after detaching (Ctrl-b d)
./dev.sh restart frontend # bounce a single windowFor local TAP debugging, use the dev compose file directly. It tracks only the
handles in TAP_DEV_HANDLES, seeds TAP via /repos/add, and starts the full
local stack, including clustering.
TAP_DEV_HANDLES="matteomarjanovic.com,zeroassembly.site" \
docker compose -f docker-compose.dev.yml up -d --buildAdd more tracked repos by appending more comma-separated handles to
TAP_DEV_HANDLES.
To wipe the dev stack completely:
docker compose -f docker-compose.dev.yml down -vcd inference
pip install -r requirements.txt
uvicorn main:app --reloadEndpoints: POST /embed/image, POST /embed/text, POST /analyze/image, GET /health
/analyze/image returns an embedding, dominant-color palette, and image dimensions in one call — used by the appview when indexing new saves.
Currents ships with a first-class atproto labeler. New saves are auto-classified for NSFW / violence / AI-generated content inside the same SigLIP2 pass that produces the embedding, suspect content lands in the moderation review queue at /moderation/queue, and reviewer decisions produce signed labels exposed via com.atproto.label.subscribeLabels / queryLabels so Bluesky clients honor them too.
- Architecture deep-dive:
MODERATION.md - Deployment walkthrough (keypair, DNS, publishing the service record):
MODERATION_DEPLOYMENT.md
See appview/README.md for full AppView configuration and OAuth docs.