- README reescrito: ejemplos CLI corregidos (flags van en el subcomando scrape), webapp+doctor documentados, requisitos por OS, cookies, datos generados, migracion de maquina - CLAUDE.md actualizado: conteo de tests, refs de linea reparadas, scripts nuevos, checklist de actualizacion de docs - AGENTS.md nuevo: entrada estandar para cualquier agente de codigo (mapa de modulos, comandos, reglas de oro, punteros a docs) - docs/GETTING-STARTED.md: de cero a webapp por OS con troubleshooting - docs/CONFIG.md: referencia completa de las ~25 claves de config - docs/COOKIES.md: adquisicion, import (web/navegador/CLI), rotacion y seguridad - docs/backlog.md reemplaza OPPORTUNITIES.md (distilado: shipped vs pendiente) - auditorias movidas a docs/audits/ y CLIPPER-COMPARISON-AUDIT.md versionado
4.4 KiB
AGENTS.md
Guía de entrada para cualquier agente de código (Claude Code, Cursor, opencode, ZCode, ...) que vaya a trabajar en este repo. Léela antes de tocar nada.
Qué es (en 5 líneas)
Plataforma 100% local de minería de contenido de creadores de YouTube. yt-dlp extrae metadatos + transcripciones de canales completos; todo se guarda en SQLite (con FTS5) y se renderiza a notas Markdown estilo Obsidian. Dos superficies: CLI yt-scraper (Click) y webapp FastAPI con SPA vanilla (Alpine). Sin auth, sin deploy remoto, sin features de IA (regla de alcance explícita en docs/superpowers/specs/2026-07-26-platform-design.md §14).
Arquitectura profunda, decisiones y trampas: CLAUDE.md — es la referencia principal; no la dupliques aquí.
Mapa de módulos (src/yt_scraper/)
| Módulo | Responsabilidad |
|---|---|
cli.py |
CLI Click (yt-scraper); fachada del pipeline. Sin subcomando = scrape completo |
config.py |
Dataclasses Config/DelayConfig/YtDlpConfig/SyncConfig + load_config |
discover.py |
yt-dlp --flat-playlist → VideoRef[]; discover_incremental (ventana + overlap) |
extract.py |
extract_info → metadatos + subtítulos; pick_subtitle (json3 > srv1 > vtt) |
parse.py |
JSON3/VTT → Segment{start, end, text} |
chapters.py |
align_chapters: capítulos ↔ segmentos → secciones |
pipeline.py |
process_video(): la unidad de trabajo por vídeo (extract→parse→store→render) |
store.py |
Única capa de datos: SQLite a mano (WAL, FTS5, migraciones idempotentes) |
segments.py |
Camino inverso .md → DB (backfill_from_markdown, reconcile_markdown) |
render.py |
Jinja2 → Markdown con frontmatter YAML (templates/video.md.j2) |
ratelimit.py |
Políticas de red: Pacer global, backoff exponencial, ThrottleGuard |
cookies.py |
Vault de cookies Netscape (import, activación, caducidad) |
monitor.py |
Watch loop (discovery periódico) |
export.py |
Export json/csv/srt/html |
analysis.py |
Top words, wordcloud, timeline |
_yt_http.py |
yt_get(): toda petición HTTP directa a CDNs de YouTube (UA + Referer) |
webapp/ |
FastAPI: app.py (create_app), api.py (routers), jobs.py (JobManager), static/ (SPA Alpine) |
Comandos esenciales
uv sync --all-extras # o: pip install -e ".[dev,web,analysis]"
uv run python -m pytest -q # suite hermética (~240 tests, 24 archivos, sin red)
python -m uvicorn yt_scraper.webapp.app:app --port 8000 # webapp manual
yt-scraper --help # CLI; ej: yt-scraper scrape --dry-run --limit 10
make serve # macOS/Linux; Windows: start-server.bat / stop-server.bat
Todo se ejecuta desde la raíz del repo: las rutas de config.yaml se resuelven relativas al CWD.
Reglas de oro
- No toques
data/nicookies/: contienen la biblioteca real y sesiones de YouTube (equivalente a contraseñas). Están gitignored; nunca las commitees ni pegues su contenido. - Tests herméticos: solo
tmp_path+monkeypatch, cero red.yt_dlp.YoutubeDLse fakea (vertests/test_webapp_jobs.py). - Handlers con I/O de red en la webapp:
def, noasync def(FastAPI manda losasync defal event loop y congelan el servidor; losdefvan al threadpool). Excepción:stream_job, que devuelve el SSE. - Mantén CLAUDE.md al día cuando cambies decisiones de arquitectura o contratos (plantilla ↔ regex, endpoints, flags). Hay checklist al final de ese archivo.
- LF, no CRLF:
.gitattributesfuerza LF para código y docs (*.bat/*.ps1salen en CRLF). No lo deshagas; no añades^M. - Una feature se implementa en
pipeline/storey se expone dos veces (subcomando CLI + endpoint webapp). No dupliques lógica en la capa web. yt-dlpes la única interfaz con YouTube; el resto de peticiones HTTP van por_yt_http.yt_get().
Punteros
- CLAUDE.md — arquitectura profunda, invariantes, incidentes y porqués.
- docs/GETTING-STARTED.md — máquina nueva desde cero por OS.
- docs/CONFIG.md — referencia completa de
config.yaml. - docs/COOKIES.md — guía de cookies (export, import, rotación, seguridad).
- docs/superpowers/specs/ — specs de diseño históricos (fuente de verdad de decisiones; donde el código difiere, gana el código).