Files
tapir/README.md
T
mathiasandClaude Opus 4.8 61796db16b feat(cmd): wire auth/run dispatcher + demo docs
main.go dispatches `tapir auth` (interactive OAuth → persist refresh token via
SecretStore) and `tapir run` (wire YouTube source + local summarizer + store
sink, build engine, run the dedup-aware loop). Config-driven so live creds plug
in at demo time; SIGINT stops the loop cleanly. Block kept minimal so Worker E's
list/show cases union cleanly at merge.

Add .env.example documenting every TAPIR_* var and a README demo runbook. Pin
the summarizer alias-as-config decision and record the max_tokens fix in
docs/homelab-integration.md (clears two `confirm` items).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 21:03:21 +02:00

78 lines
4.0 KiB
Markdown

# 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`](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`](DECISIONS.md) | Architecture Decision Records (append-only). Why Go, why no Supabase, standalone-first, captions-first, etc. |
| [`docs/architecture/architecture.md`](docs/architecture/architecture.md) | C4 context + container diagrams, key sequence diagrams, and the Clean Architecture layering (Mermaid). |
| [`docs/data-model.md`](docs/data-model.md) | Entities and the per-user isolation model (Stage 0 / Stage 1 scope). |
| [`docs/use-cases/`](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`](.env.example) to `.env` and fill it in (no
secrets are committed; at demo time source them from op, e.g. `op run -- ...`).
```sh
# 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.