docs: documentacion completa para humanos y agentes IA
- 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
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# 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](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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
1. **No toques `data/` ni `cookies/`**: contienen la biblioteca real y sesiones de YouTube (equivalente a contraseñas). Están gitignored; nunca las commitees ni pegues su contenido.
|
||||
2. **Tests herméticos**: solo `tmp_path` + `monkeypatch`, cero red. `yt_dlp.YoutubeDL` se fakea (ver `tests/test_webapp_jobs.py`).
|
||||
3. **Handlers con I/O de red en la webapp: `def`, no `async def`** (FastAPI manda los `async def` al event loop y congelan el servidor; los `def` van al threadpool). Excepción: `stream_job`, que devuelve el SSE.
|
||||
4. **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.
|
||||
5. **LF, no CRLF**: `.gitattributes` fuerza LF para código y docs (`*.bat`/`*.ps1` salen en CRLF). No lo deshagas; no añades `^M`.
|
||||
6. Una feature se implementa en `pipeline`/`store` y se expone dos veces (subcomando CLI + endpoint webapp). No dupliques lógica en la capa web.
|
||||
7. `yt-dlp` es la única interfaz con YouTube; el resto de peticiones HTTP van por `_yt_http.yt_get()`.
|
||||
|
||||
## Punteros
|
||||
|
||||
- [CLAUDE.md](CLAUDE.md) — arquitectura profunda, invariantes, incidentes y porqués.
|
||||
- [docs/GETTING-STARTED.md](docs/GETTING-STARTED.md) — máquina nueva desde cero por OS.
|
||||
- [docs/CONFIG.md](docs/CONFIG.md) — referencia completa de `config.yaml`.
|
||||
- [docs/COOKIES.md](docs/COOKIES.md) — guía de cookies (export, import, rotación, seguridad).
|
||||
- [docs/superpowers/specs/](docs/superpowers/specs/) — specs de diseño históricos (fuente de verdad de decisiones; donde el código difiere, gana el código).
|
||||
Reference in New Issue
Block a user