mathias a38002df80
CI / Lint / Test / Vet (push) Successful in 6s
CI / Build & Import (push) Failing after 1s
CI / Mirror to GitHub (push) Has been skipped
merge: demo wiring — tapir auth/run + config (Worker F, agent/demo-wiring)
# Conflicts:
#	cmd/tapir/main.go
2026-06-02 21:29:48 +02:00
2026-06-02 11:06:13 +00:00

tapir

Watches a user's YouTube/Vimeo subscriptions and, when a subscribed channel posts a new video, summarizes it into highlights and takeaways using a local-first AI stack with an optional, per-user BYO-AI fallback. Standalone-first; feeding a personal knowledge base ("brain") is one optional sink, not the reason Tapir exists. Written in Go.

Status

Pre-code. The repository currently holds the guardrail documentation — vision, decisions, architecture, data model, and behavior specs — committed before implementation so the design intent is version-controlled and the build has something to be checked against.

Read these first (the guardrails)

Doc What it is
VISION.md Product vision, principles, and the staged Definition of Success. Stage 0 ("useful to me") is the gate before any multi-user work.
DECISIONS.md Architecture Decision Records (append-only). Why Go, why no Supabase, standalone-first, captions-first, etc.
docs/architecture/architecture.md C4 context + container diagrams, key sequence diagrams, and the Clean Architecture layering (Mermaid).
docs/data-model.md Entities and the per-user isolation model (Stage 0 / Stage 1 scope).
docs/use-cases/ Gherkin .feature files — the BDD behavior spec that seeds the test suite.

Approach

  • Clean Architecture / ports & adapters. A provider- and sink-agnostic engine depends only on interfaces (VideoSource, Summarizer, Sink, SecretStore). YouTube, Vimeo, the AI router, the user store, and the brain sink are adapters. "Standalone vs homelab" is a wiring choice, not two codebases.
  • TDD/BDD. The .feature files are the living behavior spec; the use-case core is tested through fake adapters. Behavior is specified as executable scenarios, not prose that drifts.
  • Trunk-Based Development. Commit directly to main, one logical change per commit, every commit deployable (see ADR-009). CI is the quality gate.

Running the Stage-0 demo

Tapir runs on your own YouTube account: authorize once, then run the watch→summarize→deliver loop. All configuration is via TAPIR_* environment variables — copy .env.example to .env and fill it in (no secrets are committed; at demo time source them from op, e.g. op run -- ...).

# 1. configure (UUID user id, gateway URL+key, Postgres DSN, YouTube OAuth app,
#    summarizer model). See .env.example for every variable.
cp .env.example .env && $EDITOR .env
set -a && . ./.env && set +a          # export them into the shell

go build -o bin/tapir ./cmd/tapir

# 2. one-time: authorize YouTube. Opens a consent URL, captures the redirect on
#    TAPIR_OAUTH_REDIRECT_ADDR, and stores the refresh token via the SecretStore
#    (a 0600 file at Stage 0). The token is never logged.
./bin/tapir auth

# 3. run: detect new videos across your subscriptions, summarize, deliver to the
#    store. Unset TAPIR_POLL_INTERVAL = single pass; set it (e.g. 15m) to loop.
./bin/tapir run

Live prerequisites at demo time: the LiteLLM gateway reachable (TAPIR_GATEWAY_URL + a valid key — resolve from op, the documented sk-local-123 is stale), a Postgres DSN (TAPIR_DB_DSN, migrations apply on first connect), and a registered YouTube OAuth client whose authorized redirect URI matches TAPIR_OAUTH_REDIRECT_ADDR. The summarizer model (TAPIR_SUMMARIZER_MODEL, default koala/phi4-mini) is overridable; pick the final alias when the gateway is reachable (see docs/homelab-integration.md).

Conventions

Reuses homelab conventions: Go, Dex for identity, ESO + 1Password for secrets, Postgres for persistence. No new auth or secrets system (ADR-002).

Next

First implementation step: scaffold the Go service (engine + interfaces + the copied llm package), captions-first, with the store and brain sink adapters — decomposable into independent units suitable for a Claude Code swarm. Tracked as the first build issue.

S
Description
Watches a user's YouTube/Vimeo subscriptions and summarizes new videos (highlights + takeaways) via local-first AI with optional BYO-AI fallback. Standalone-first; brain is one optional sink. Go.
Readme
4.5 MiB
Languages
Go 91.3%
Python 4.5%
templ 4%
Dockerfile 0.2%