fix(using-yt-tools): resolve binaries via venv/winget fallback v0.3.0
Skill no longer aborts on bare `Get-Command yt-frames` miss — binaries installed in project-local venv or winget cache (Gyan.FFmpeg_*) are valid install sites, just not on PATH for fresh shells. New Step 0 in both flows: probe PATH first, then known install locations (venv Scripts/bin, winget Gyan.FFmpeg_*/ffmpeg-*-full_build/bin); abort only if both empty. PATH-prepend pattern documented (full-path to yt-frames.exe is insufficient — child yt-dlp/ffmpeg need prepend too). Failure modes table updated: removed 'restart CC session' advice — agent can't restart itself, and resolve-fallback makes it unnecessary. MINOR bump per project-discipline (behaviour change in resolve logic).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: using-yt-tools
|
||||
version: 0.2.3
|
||||
version: 0.3.0
|
||||
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 — другие тулзы.
|
||||
---
|
||||
|
||||
@@ -22,25 +22,51 @@ Iterative-watching YouTube для агента: clean-markdown транскри
|
||||
- Шаги: 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).
|
||||
Оба flow предполагают, что `yt-tools` CLI установлен из `~/projects/.common/lib/yt-tools/` (project-local venv). Бинари могут не быть на PATH текущей сессии — это норма, особенно после свежего `winget install`. **Никогда не abort'ить по голому `Get-Command yt-frames` / `which yt-frames`** — сначала прогнать резолв (см. Prerequisites → Locating binaries).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**CLI invocation** — один из двух вариантов (выбери по ситуации):
|
||||
### Locating binaries
|
||||
|
||||
| Вариант | Команда | Trade-off |
|
||||
|---|---|---|
|
||||
| **A. Активация venv** | Windows: `& ~/projects/.common/lib/yt-tools/.venv/Scripts/Activate.ps1`<br>Linux/macOS: `source ~/projects/.common/lib/yt-tools/.venv/bin/activate` | Одна команда, но меняет shell state |
|
||||
| **B. Full-path** | `~/projects/.common/lib/yt-tools/.venv/Scripts/yt-frames.exe URL ...` (Windows)<br>`~/projects/.common/lib/yt-tools/.venv/bin/yt-frames URL ...` (Linux/macOS) | Изолированно, но длиннее в каждом вызове |
|
||||
Скил ничего не предполагает про активный PATH. **Step 0 каждого flow** — резолв путей для `yt-frames`/`yt-transcript` и `ffmpeg` (+ `yt-dlp`, поставляется в том же venv). Если резолвится через fallback — используй PATH-prepend в каждом вызове (см. Invoke pattern ниже). Abort'ить **только** если бинаря нет ни на PATH, ни в известных install-локациях.
|
||||
|
||||
После активации или full-path доступны:
|
||||
- `yt-transcript`, `yt-frames`, `yt-watch`, `yt-tools`
|
||||
**yt-tools CLI** (один venv даёт все четыре: `yt-frames`, `yt-transcript`, `yt-watch`, `yt-tools`; туда же ставится `yt-dlp`):
|
||||
|
||||
**Внешние бинари** (любая ОС):
|
||||
- `yt-dlp` — fetches metadata + source mp4
|
||||
- `ffmpeg` — muxes streams + extracts frames
|
||||
1. PATH: `Get-Command yt-frames` (pwsh) / `command -v yt-frames` (bash)
|
||||
2. Project-local venv:
|
||||
- Windows: `~/projects/.common/lib/yt-tools/.venv/Scripts/yt-frames.exe`
|
||||
- Linux/macOS: `~/projects/.common/lib/yt-tools/.venv/bin/yt-frames`
|
||||
3. Если ни PATH, ни venv — install hint: `python -m venv ~/projects/.common/lib/yt-tools/.venv && ~/projects/.common/lib/yt-tools/.venv/{Scripts,bin}/pip install -e ~/projects/.common/lib/yt-tools/`; стоп.
|
||||
|
||||
Полный 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 не перечитывает.
|
||||
**ffmpeg**:
|
||||
|
||||
1. PATH: `Get-Command ffmpeg` / `command -v ffmpeg`
|
||||
2. Windows winget cache (версия плавающая, глобь):
|
||||
`~/AppData/Local/Microsoft/WinGet/Packages/Gyan.FFmpeg_Microsoft.Winget.Source_*/ffmpeg-*-full_build/bin/ffmpeg.exe`
|
||||
3. macOS Homebrew: `/opt/homebrew/bin/ffmpeg` (Apple Silicon) или `/usr/local/bin/ffmpeg` (Intel)
|
||||
4. Linux: `/usr/bin/ffmpeg` (apt) или `/usr/local/bin/ffmpeg`
|
||||
5. Если ни одна локация — install hint per-ОС (`winget install Gyan.FFmpeg` / `brew install ffmpeg` / `apt install ffmpeg`); стоп. **Не** проси юзера restart'ить CC — продолжай резолв-логику в той же сессии после установки, либо подскажи, что новой сессии PATH подхватится сам.
|
||||
|
||||
### Invoke pattern
|
||||
|
||||
`yt-frames` сам спавнит `yt-dlp` и `ffmpeg` через `subprocess.run([..., "ffmpeg", ...])` — full-path к самому `yt-frames.exe` **не хватит**, нужен PATH-prepend, чтобы child процессы тоже их видели.
|
||||
|
||||
```bash
|
||||
# bash / git-bash — после резолва через fallback
|
||||
FFDIR=$(dirname "$(ls ~/AppData/Local/Microsoft/WinGet/Packages/Gyan.FFmpeg_*/ffmpeg-*-full_build/bin/ffmpeg.exe 2>/dev/null | head -1)")
|
||||
YTBIN=~/projects/.common/lib/yt-tools/.venv/Scripts # /bin на Linux/macOS
|
||||
PATH="$FFDIR:$YTBIN:$PATH" yt-frames <url> --timestamps 1:23,4:56
|
||||
```
|
||||
|
||||
```powershell
|
||||
# pwsh — glob по плавающей версии ffmpeg
|
||||
$ff = (Get-ChildItem "$HOME\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_*\ffmpeg-*-full_build\bin\ffmpeg.exe" -ErrorAction SilentlyContinue | Select-Object -First 1).DirectoryName
|
||||
$ytbin = "$HOME\projects\.common\lib\yt-tools\.venv\Scripts"
|
||||
$env:PATH = "$ff;$ytbin;" + $env:PATH
|
||||
yt-frames <url> --timestamps 1:23,4:56
|
||||
```
|
||||
|
||||
Если оба нашлись напрямую на PATH (`Get-Command` вернул что-то) — pre-pend не нужен, зови как обычно.
|
||||
|
||||
## Inputs
|
||||
|
||||
@@ -56,7 +82,7 @@ Iterative-watching YouTube для агента: clean-markdown транскри
|
||||
### Flow A — iterative-watch
|
||||
|
||||
```
|
||||
0. Activate venv: & ~/projects/.common/lib/yt-tools/.venv/Scripts/Activate.ps1 (Windows) или source ~/projects/.common/lib/yt-tools/.venv/bin/activate (Linux/macOS)
|
||||
0. Резолв yt-frames + ffmpeg per Prerequisites → Locating binaries; собрать PATH-prepend если резолв через fallback
|
||||
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
|
||||
@@ -64,8 +90,6 @@ Iterative-watching YouTube для агента: clean-markdown транскри
|
||||
5. Answer the user, citing both transcript paragraph and frame contents
|
||||
```
|
||||
|
||||
Альтернатива: skip шаг 0, используй full-path в каждом вызове (см. Prerequisites).
|
||||
|
||||
**Stdout contract per CLI** (бери последнюю строку, формат зависит от CLI):
|
||||
|
||||
- `yt-transcript`, `yt-watch` — одна строка на stdout: bare absolute path артефакта (`<abs>/transcript.md` или `<abs>/watch.md`).
|
||||
@@ -76,7 +100,7 @@ Warnings и errors уходят в stderr (`warning: …`, `error: …`); stdout
|
||||
### Flow B — targeted-frames
|
||||
|
||||
```
|
||||
0. Activate venv: & ~/projects/.common/lib/yt-tools/.venv/Scripts/Activate.ps1 (Windows) или source ~/projects/.common/lib/yt-tools/.venv/bin/activate (Linux/macOS)
|
||||
0. Резолв yt-frames + ffmpeg per Prerequisites → Locating binaries; собрать PATH-prepend если резолв через fallback
|
||||
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
|
||||
@@ -91,9 +115,9 @@ Warnings и errors уходят в stderr (`warning: …`, `error: …`); stdout
|
||||
|
||||
| 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-transcript` / `yt-frames` not on PATH | yt-tools pkg не pip-installed **либо** venv создан, но не на PATH | Прогнать резолв per Prerequisites → Locating binaries. Abort только если и venv-локация пуста — тогда install-hint, стоп |
|
||||
| `yt-dlp not found on PATH` (от child процесса) | `yt-dlp` есть в venv, но PATH-prepend не собран | Пересобери PATH-prepend (Prerequisites → Invoke pattern); `yt-dlp` ставится тем же `pip install -e` что и `yt-frames` |
|
||||
| `ffmpeg not found on PATH` (от child процесса) | ffmpeg установлен, но в winget-кэше/Homebrew/etc., не на PATH сессии | Прогнать ffmpeg-резолв per Prerequisites, prepend в PATH. Abort только если ни одна локация не нашла бинаря — install per ОС. **Не** требовать 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 с явными таймкодами если уместно |
|
||||
|
||||
Reference in New Issue
Block a user