Files
claude-skills/skills/using-yt-tools/SKILL.md
vitya 9fdd48b605 fix(using-yt-tools): tighten SKILL.md v0.2.0→0.2.1
- description: 860→340 chars (remove implementation fluff)
- timestamps: add bare seconds example (123 → 2:03)
- stdout: clarify "CLI designed for single-line EOF"
- cache: add cumulative warning (20 videos = 1-4 GB)
- failure modes: add malformed URL to yt-dlp failures

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:06:38 +03:00

110 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: using-yt-tools
version: 0.2.1
description: Two flows for YouTube content. **Iterative-watch** (summary/exploration): transcript with [mm:ss] anchors → pick moments → extract frames. **Targeted-frames** (specific timestamps): extract frames directly, no transcript. Triggers: "что в ролике", "о чём видео", "video summary", "youtube transcript", "покажи кадр на N", или любой youtube.com URL. CLI в `~/projects/.common/lib/yt-tools/`. YouTube-only; для Vimeo/Twitch/local — другие тулзы.
---
# using-yt-tools
Iterative-watching YouTube для агента: clean-markdown транскрипт с `[mm:ss]`-якорями → агент решает, какие моменты интересны → targeted frame extraction по таймкодам → агент видит кадры через `Read`. Альтернативный flow — если юзер уже назвал таймкоды, идём прямо за кадрами без транскрипта.
## When to use
Два различных flow, выбор по user intent:
**Flow A — iterative-watch** (exploration / summary):
- Юзер спрашивает что в ролике, хочет summary, хочет узнать о чём видео.
- Шаги: fetch transcript → read → pick interesting moments → extract those frames → Read frames.
- Trigger phrases: «что в этом ролике», «о чём ролик», «расшифровка YouTube», «video summary», «youtube transcript», «watch this video».
**Flow B — targeted-frames** (specific moments):
- Юзер уже назвал конкретные таймкоды; транскрипт — лишняя работа.
- Шаги: extract frames at given timestamps → Read frames.
- Trigger phrases: «покажи кадр на N», «посмотри момент N», «что показано на N», «show frame at N».
Оба flow предполагают, что `yt-tools` CLI установлен из `~/projects/.common/lib/yt-tools/`. Если `yt-transcript` / `yt-frames` отсутствуют на PATH — abort с install-hint (см. Prerequisites).
## Prerequisites
CLI entry-points на PATH (из `pip install -e ~/projects/.common/lib/yt-tools/` внутри venv):
- `yt-transcript`, `yt-frames`, `yt-watch`, `yt-tools`
Внешние бинари (любая ОС):
- `yt-dlp` — fetches metadata + source mp4
- `ffmpeg` — muxes streams + extracts frames
Если что-то отсутствует, CLI выдаёт явное `"X not found on PATH"`. Скажи юзеру и стоп.
Полный install per-OS — в `~/projects/.common/lib/yt-tools/README.md`. **Windows-gotcha:** после `winget install Gyan.FFmpeg` или `winget install yt-dlp.yt-dlp` нужен restart терминала (и Claude Code session) — winget пишет в per-user PATH, который текущий shell не перечитывает.
## Inputs
| Flow | Required | Optional |
|---|---|---|
| A — iterative-watch | YouTube URL или bare 11-char video id | `--lang ru,en` для non-English subs; `--out PATH` |
| B — targeted-frames | YouTube URL + timestamps (`mm:ss`, `h:mm:ss`, или bare seconds: `123` → 2:03) | `--no-cache-source` (stream вместо кеша source.mp4); `--out DIR` |
Оба flow пишут в `<cwd>/yt-cache/<video-id>/` по умолчанию.
## Steps
### Flow A — iterative-watch
```
1. yt-transcript <url> → ./yt-cache/<vid>/transcript.md
2. Read transcript.md, find [mm:ss] anchors that match the question
3. yt-frames <url> --timestamps 1:23,4:56,… → ./yt-cache/<vid>/frames/frame_*.jpg
4. Read each frame_*.jpg via the vision tool
5. Answer the user, citing both transcript paragraph and frame contents
```
Last line каждого CLI's stdout — absolute path артефакта (CLI designed для single-line EOF output). Не парси текст вокруг, бери конец stdout.
### Flow B — targeted-frames
```
1. Parse user's timestamps (mm:ss / h:mm:ss / bare seconds — все работают)
2. yt-frames <url> --timestamps 1:23,4:56,… → ./yt-cache/<vid>/frames/frame_*.jpg
3. Read each frame_*.jpg
4. Answer the user, referencing each frame by its [mm:ss] label
```
Без transcript fetch. Если потом юзер спросит «что говорилось в тот момент?», переключайся на Flow A на том же URL — `source.mp4` cache переиспользуется, повторного download нет.
## Failure modes
Все failures abort cleanly; никогда не оставляй наполовину готовое состояние.
| Symptom | Cause | Action |
|---|---|---|
| `yt-transcript` / `yt-frames` not on PATH | yt-tools pkg не pip-installed | Скажи юзеру install per `~/projects/.common/lib/yt-tools/README.md`; стоп |
| `yt-dlp not found on PATH` | Внешний бин отсутствует | Дай install command для ОС юзера; стоп |
| `ffmpeg not found on PATH` | Внешний бин отсутствует | То же; на Windows после `winget install Gyan.FFmpeg` юзер должен restart терминала + CC session |
| `yt-dlp source download failed (exit N) \| stderr: …` | Network / private / age-gated / region-locked / malformed URL | Выведи captured stderr verbatim; не retry |
| `yt-dlp --dump-json failed` | То же, но на metadata step | То же |
| `Subtitles disabled` от `youtube-transcript-api` | Канал отключил CC | Для Flow A это fatal — скажи юзеру, предложи Flow B с явными таймкодами если уместно |
| Юзер дал не-YouTube URL (Vimeo / Twitch / local mp4) | Out of scope | Стоп; скажи что скил YouTube-only |
## Side effects
- Writes под `<cwd>/yt-cache/<video-id>/`:
- `transcript.md` (Flow A)
- `source.mp4` (≤720p, оба flow если без `--no-cache-source`)
- `frames/frame_<mmss>.jpg` per extracted frame
- Network: yt-dlp вытягивает metadata + опционально source.mp4; `youtube-transcript-api` вытягивает subs
- Никакого внешнего state не мутируется — чисто local-fs side effects
- `source.mp4` может быть ~50-200 MB на 720p / 10-минутный ролик; кеш переиспользуется между запусками. **Warning:** cumulative — 20 роликов = 1-4 GB на диске.
Cache hygiene: `yt-tools cache list` показывает usage, `yt-tools cache prune --older-than 7d` чистит.
## What NOT to do
- **Не запускай Flow A когда юзер уже дал таймкоды.** «Посмотри 1:23 и 4:56» → сразу Flow B. Fetching transcript first — чистая трата.
- **Не bulk-extract «на всякий случай».** Flow A берёт кадры из транскрипта, Flow B — из явного user input. Никогда `--mode interval --interval 5s` «to be safe».
- **Не используй `yt-watch` как default Flow A renderer.** `yt-watch` комбинирует transcript + scene-frames в один doc — тяжелее (требует ffmpeg scene-detect pass на source.mp4). Бери только когда юзер хочет один self-contained document.
- **Не shell-quote URLs в одну command строку.** Используй CLI list-form (он уже list-form в `subprocess.run`); YouTube URLs содержат `?` и `&`, которые ломают naive quoting.
- **Не retry на yt-dlp failures.** Failure здесь значит видео реально недоступно (private / region / age) или у юзера broken auth. Retries — трата токенов.
- **Не пересказывай / не переводи transcript в свой ответ молча.** Артефакт — для твоего reasoning; цитируй с `[mm:ss]`-якорем когда приводишь пассаж.
- **Не вызывай скил на non-YouTube URL.** Vimeo / Twitch / TikTok / local mp4 — out of scope. Бери другие тулзы (или yt-dlp напрямую).
- **Не пиши результаты в произвольные пути.** По умолчанию `<cwd>/yt-cache/<vid>/`; явный `--out` только если юзер просил.