youtube-advisor 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- youtube_advisor-0.1.0/.github/workflows/release.yml +45 -0
- youtube_advisor-0.1.0/.gitignore +12 -0
- youtube_advisor-0.1.0/AGENTS.md +19 -0
- youtube_advisor-0.1.0/CHANGELOG.md +37 -0
- youtube_advisor-0.1.0/CONTRIBUTING.md +58 -0
- youtube_advisor-0.1.0/LICENSE +21 -0
- youtube_advisor-0.1.0/PKG-INFO +255 -0
- youtube_advisor-0.1.0/README.md +189 -0
- youtube_advisor-0.1.0/SKILL.md +225 -0
- youtube_advisor-0.1.0/THIRD_PARTY_LICENSES.md +28 -0
- youtube_advisor-0.1.0/docs/logo.png +0 -0
- youtube_advisor-0.1.0/pyproject.toml +65 -0
- youtube_advisor-0.1.0/references/.gitkeep +0 -0
- youtube_advisor-0.1.0/scripts/install.sh +71 -0
- youtube_advisor-0.1.0/scripts/status.sh +31 -0
- youtube_advisor-0.1.0/src/youtube_advisor/__init__.py +2 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_cookies.py +115 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_llm.py +40 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_md.py +74 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_naming.py +7 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_paths.py +5 -0
- youtube_advisor-0.1.0/src/youtube_advisor/_progress.py +78 -0
- youtube_advisor-0.1.0/src/youtube_advisor/bootstrap.py +484 -0
- youtube_advisor-0.1.0/src/youtube_advisor/build_embeddings.py +139 -0
- youtube_advisor-0.1.0/src/youtube_advisor/build_index.py +42 -0
- youtube_advisor-0.1.0/src/youtube_advisor/cli.py +125 -0
- youtube_advisor-0.1.0/src/youtube_advisor/eval_runner.py +81 -0
- youtube_advisor-0.1.0/src/youtube_advisor/fetch_channel.py +155 -0
- youtube_advisor-0.1.0/src/youtube_advisor/filters.py +73 -0
- youtube_advisor-0.1.0/src/youtube_advisor/gen_benchmark.py +114 -0
- youtube_advisor-0.1.0/src/youtube_advisor/gen_skill_md.py +108 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/__init__.py +0 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/captions_api.py +92 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/captions_ytdlp.py +68 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/normalize.py +45 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/orchestrator.py +144 -0
- youtube_advisor-0.1.0/src/youtube_advisor/ingest/whisper.py +65 -0
- youtube_advisor-0.1.0/src/youtube_advisor/postrun_guide.py +117 -0
- youtube_advisor-0.1.0/src/youtube_advisor/search.py +144 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/advisor.AGENTS.md.tmpl +36 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/advisor.README.md.tmpl +31 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/advisor.SKILL.md.tmpl +41 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/answer_template.md.tmpl +11 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/benchmark.json.tmpl +6 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/search.py.tmpl +15 -0
- youtube_advisor-0.1.0/src/youtube_advisor/templates/workflow.md.tmpl +54 -0
- youtube_advisor-0.1.0/src/youtube_advisor/update.py +241 -0
- youtube_advisor-0.1.0/tests/__init__.py +0 -0
- youtube_advisor-0.1.0/tests/conftest.py +31 -0
- youtube_advisor-0.1.0/tests/fixtures/sample.vtt +10 -0
- youtube_advisor-0.1.0/tests/fixtures/yc_flat.json +1 -0
- youtube_advisor-0.1.0/tests/test_bootstrap.py +296 -0
- youtube_advisor-0.1.0/tests/test_build_embeddings.py +210 -0
- youtube_advisor-0.1.0/tests/test_build_index.py +114 -0
- youtube_advisor-0.1.0/tests/test_captions_api.py +95 -0
- youtube_advisor-0.1.0/tests/test_captions_ytdlp.py +96 -0
- youtube_advisor-0.1.0/tests/test_cookies.py +126 -0
- youtube_advisor-0.1.0/tests/test_e2e.py +229 -0
- youtube_advisor-0.1.0/tests/test_eval_runner.py +162 -0
- youtube_advisor-0.1.0/tests/test_fetch_channel.py +110 -0
- youtube_advisor-0.1.0/tests/test_filters.py +74 -0
- youtube_advisor-0.1.0/tests/test_gen_benchmark.py +165 -0
- youtube_advisor-0.1.0/tests/test_gen_skill_md.py +142 -0
- youtube_advisor-0.1.0/tests/test_normalize.py +87 -0
- youtube_advisor-0.1.0/tests/test_orchestrator.py +225 -0
- youtube_advisor-0.1.0/tests/test_postrun_guide.py +145 -0
- youtube_advisor-0.1.0/tests/test_progress.py +67 -0
- youtube_advisor-0.1.0/tests/test_search.py +240 -0
- youtube_advisor-0.1.0/tests/test_templates.py +110 -0
- youtube_advisor-0.1.0/tests/test_update.py +213 -0
- youtube_advisor-0.1.0/tests/test_whisper.py +162 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- name: Extract release notes from CHANGELOG
|
|
20
|
+
id: notes
|
|
21
|
+
run: |
|
|
22
|
+
VERSION="${GITHUB_REF#refs/tags/v}"
|
|
23
|
+
NOTES=$(awk -v ver="$VERSION" '
|
|
24
|
+
/^## \[/ {
|
|
25
|
+
if (capture) exit
|
|
26
|
+
if (index($0, "[" ver "]")) { capture = 1; next }
|
|
27
|
+
}
|
|
28
|
+
capture { print }
|
|
29
|
+
' CHANGELOG.md)
|
|
30
|
+
if [ -z "$NOTES" ]; then
|
|
31
|
+
echo "No CHANGELOG entry for v$VERSION" >&2
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
{
|
|
35
|
+
echo "notes<<NOTES_EOF"
|
|
36
|
+
echo "$NOTES"
|
|
37
|
+
echo "NOTES_EOF"
|
|
38
|
+
} >> "$GITHUB_OUTPUT"
|
|
39
|
+
|
|
40
|
+
- name: Create GitHub Release
|
|
41
|
+
uses: softprops/action-gh-release@v2
|
|
42
|
+
with:
|
|
43
|
+
name: ${{ github.ref_name }}
|
|
44
|
+
body: ${{ steps.notes.outputs.notes }}
|
|
45
|
+
prerelease: ${{ contains(github.ref_name, '-') }}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# youtube-advisor — build a Claude Code advisor from any YouTube channel
|
|
2
|
+
|
|
3
|
+
> AGENTS.md is a tool-agnostic pointer for non-Claude-Code AI agents (Codex CLI, Cursor, Continue.dev, Aider, Goose, …). Setup is the only thing that differs per tool; the workflow, rules, and worked examples are canonical in [SKILL.md](./SKILL.md).
|
|
4
|
+
|
|
5
|
+
## Your tool → how to wire
|
|
6
|
+
|
|
7
|
+
| Tool | Setup | Invoke |
|
|
8
|
+
| ----------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
9
|
+
| **Claude Code** | `git clone … ~/.claude/skills/youtube-advisor` | `/youtube-advisor` then paste channel + intent |
|
|
10
|
+
| **OpenAI Codex CLI** | clone anywhere, place `AGENTS.md` at `~/.codex/AGENTS.md` (or project root) | "build me an advisor on @ycombinator" |
|
|
11
|
+
| **Cursor** | clone anywhere, copy `AGENTS.md` → `.cursor/rules/youtube-advisor.md` | mention `@youtube-advisor` or natural language |
|
|
12
|
+
| **Continue.dev** | clone anywhere, register as custom slash command in `~/.continue/config.yaml` | `/youtube-advisor <channel>` |
|
|
13
|
+
| **Aider** | clone anywhere, `aider --read <install-dir>/AGENTS.md` | natural language in chat |
|
|
14
|
+
| **Goose** (Block) | clone anywhere, add as a shell-command extension | mention youtube-advisor |
|
|
15
|
+
| **No AI at all** | clone anywhere | `youtube-advisor bootstrap --channel @yc --out ...` (see CLI in README) |
|
|
16
|
+
|
|
17
|
+
The bash CLI works in any environment with or without an AI driving it.
|
|
18
|
+
|
|
19
|
+
> See [SKILL.md](./SKILL.md) for the full workflow, two-action user contract, worked examples, anti-patterns, and installation prerequisites.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to youtube-advisor will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — 2026-06-06
|
|
11
|
+
|
|
12
|
+
First public beta. Build a Claude Code advisor skill from any YouTube channel.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Two-action user UX: paste a channel + intent in chat → AI builds the advisor → invoke `/<channel-slug>-advisor` to ask questions.
|
|
16
|
+
- Three-tier transcript cascade: `youtube-transcript-api` (free YT captions) → `yt-dlp` VTT fallback → local Whisper via `faster-whisper` or scriba.
|
|
17
|
+
- Hybrid retrieval: BM25 + dense embeddings (`fastembed` with `bge-small-en-v1.5` default, `bge-m3` opt-in for multilingual) fused via Reciprocal Rank Fusion.
|
|
18
|
+
- Citation-first answer contract: every answer carries verbatim quotes with `youtube.com/watch?v=ID&t=SECONDS` deep-links.
|
|
19
|
+
- LLM-drafted SKILL.md and benchmark per advisor (when `ANTHROPIC_API_KEY` is set) — OR — handoff to the AI agent in chat via `.pending-llm-draft.json` when no API key is set (`--no-llm` mode, auto-detected).
|
|
20
|
+
- Incremental updates: saved selection filter is replayed on `update`, only new videos are fetched and indexed.
|
|
21
|
+
- Eval scaffolding: generated benchmark + runner with regression detection (`--run-evals`).
|
|
22
|
+
- Selection DSL: `--channel`, `--playlist`, `--since`, `--until`, `--max`, `--title-include`, `--title-exclude`, `--ids`.
|
|
23
|
+
- Anti-bot defaults: 1–5s randomized sleep between yt-dlp requests, exponential-backoff retries on HTTP 429.
|
|
24
|
+
- Live progress: bootstrap writes `<advisor>/.progress.json` on every stage change and per-video ingest; `scripts/status.sh <advisor>` (and `youtube-advisor status <advisor>`) print a one-line snapshot for a peek from a side terminal.
|
|
25
|
+
- YouTube JS-challenge solver: yt-dlp invocations now pass `--remote-components ejs:github` (auto-detected via `yt-dlp --help` probe — silently omitted on older yt-dlp builds without the flag) and `--extractor-args youtube:formats=missing_pot` to avoid HTTP 429s and PO-token errors. Requires `deno` on PATH at runtime; `install.sh` now warns if missing.
|
|
26
|
+
- Cookie support: `--cookies-from-browser {chrome,firefox,safari,brave,edge,…}`, `--cookies <file>`, env vars `YOUTUBE_ADVISOR_COOKIES_BROWSER` / `YOUTUBE_ADVISOR_COOKIES_FILE`, and auto-discovery of `~/.config/youtube-advisor/cookies.txt`.
|
|
27
|
+
- OSS scaffolding: MIT license, scriba-style README, CONTRIBUTING, THIRD_PARTY_LICENSES, `bash scripts/install.sh` helper.
|
|
28
|
+
- Python package uses `src/` layout (`src/youtube_advisor/`).
|
|
29
|
+
- 183 tests (unit + integration + E2E).
|
|
30
|
+
|
|
31
|
+
### Known limitations
|
|
32
|
+
- Single channel per advisor (multi-channel rollups planned for v0.2).
|
|
33
|
+
- Length-based filtering (e.g. "interviews > 60 minutes") not yet a selection flag.
|
|
34
|
+
- LangDetect on update doesn't re-fire — corpus language persists from bootstrap.
|
|
35
|
+
|
|
36
|
+
[Unreleased]: https://github.com/AlexanderAbramovPav/youtube-advisor/compare/v0.1.0...HEAD
|
|
37
|
+
[0.1.0]: https://github.com/AlexanderAbramovPav/youtube-advisor/releases/tag/v0.1.0
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Contributing to youtube-advisor
|
|
2
|
+
|
|
3
|
+
Issues and pull requests welcome. A few orientation notes:
|
|
4
|
+
|
|
5
|
+
## Project layout
|
|
6
|
+
|
|
7
|
+
- `src/youtube_advisor/` — Python package (filters / fetch_channel / ingest tiers / build_index / build_embeddings / search / gen_skill_md / gen_benchmark / eval_runner / postrun_guide / bootstrap / update / cli). Uses the [src layout](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
|
|
8
|
+
- `templates/` — Jinja2 scaffolds rendered into each emitted advisor.
|
|
9
|
+
- `tests/` — unit + integration + E2E. Tier-1/Tier-2 ingest tests use mock subprocess + fixture VTT files (no live network). E2E tests mock at module boundaries and exercise the real index/search/eval pipeline.
|
|
10
|
+
|
|
11
|
+
## Running tests
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd youtube-advisor && source .venv/bin/activate
|
|
15
|
+
pytest -q # default: all unit + E2E (mocked-network only)
|
|
16
|
+
pytest -m slow # requires RUN_SLOW=1 — actual fastembed model + faster-whisper
|
|
17
|
+
pytest -m e2e # E2E only
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Adding a fixture channel
|
|
21
|
+
|
|
22
|
+
`tests/fixtures/yc_flat.json` is a `yt-dlp --flat-playlist -J` snapshot of `@ycombinator/videos`. To add another channel for testing, run:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yt-dlp --flat-playlist -J --playlist-end 5 https://www.youtube.com/@<handle>/videos > tests/fixtures/<handle>_flat.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
then patch `subprocess.run` in your test to return this JSON (see `tests/test_fetch_channel.py`).
|
|
29
|
+
|
|
30
|
+
## Swapping the embedding model
|
|
31
|
+
|
|
32
|
+
The default is `BAAI/bge-small-en-v1.5` (384-dim, 24 MB). To experiment with another `fastembed`-supported model, pass `--multilingual` to use `BAAI/bge-m3` (1 GB) or fork `youtube_advisor/build_embeddings.py` to accept a custom model name and re-run `build_embeddings` with `incremental=False` to re-encode the corpus.
|
|
33
|
+
|
|
34
|
+
## Adding language tests
|
|
35
|
+
|
|
36
|
+
Captions language is auto-detected from the YT API; advisor answer language is configurable. To add a language-specific assertion, ingest a Russian or Spanish video (e.g., a Lex Fridman interview with non-English content) and add a test that verifies `transcript_language` in the frontmatter and `corpus_language` in `corpus_meta.json`.
|
|
37
|
+
|
|
38
|
+
## Style
|
|
39
|
+
|
|
40
|
+
- Follow the project's CLAUDE.md conventions: no defensive code for impossible cases; only validate at system boundaries; minimal comments (only when the WHY is non-obvious).
|
|
41
|
+
- TDD: write the failing test first, then minimal implementation, then commit.
|
|
42
|
+
- One concern per file. Files growing past ~150 lines are a smell.
|
|
43
|
+
|
|
44
|
+
## Releasing
|
|
45
|
+
|
|
46
|
+
We use [Semantic Versioning](https://semver.org/) and maintain a [Keep a Changelog](https://keepachangelog.com/) at `CHANGELOG.md`.
|
|
47
|
+
|
|
48
|
+
To cut a release:
|
|
49
|
+
|
|
50
|
+
1. Move the `## [Unreleased]` block's entries under a new `## [X.Y.Z] — YYYY-MM-DD` heading.
|
|
51
|
+
2. Bump `version` in `pyproject.toml` to match.
|
|
52
|
+
3. Commit: `release: vX.Y.Z`.
|
|
53
|
+
4. Tag: `git tag -s vX.Y.Z -m "vX.Y.Z"`.
|
|
54
|
+
5. Push: `git push && git push --tags`.
|
|
55
|
+
|
|
56
|
+
The release workflow (`.github/workflows/release.yml`) creates a GitHub Release with the CHANGELOG entry as the body.
|
|
57
|
+
|
|
58
|
+
Tags that contain a hyphen (e.g. `v0.2.0-beta1`) are auto-marked as prereleases.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexander Abramov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: youtube-advisor
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn any YouTube channel into an AI assistant skill that answers questions with verbatim quotes and timestamped video links.
|
|
5
|
+
Project-URL: Homepage, https://github.com/AlexanderAbramovPav/youtube-advisor
|
|
6
|
+
Project-URL: Repository, https://github.com/AlexanderAbramovPav/youtube-advisor
|
|
7
|
+
Project-URL: Issues, https://github.com/AlexanderAbramovPav/youtube-advisor/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/AlexanderAbramovPav/youtube-advisor/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Releases, https://github.com/AlexanderAbramovPav/youtube-advisor/releases
|
|
10
|
+
Author: Alexander Abramov
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 Alexander Abramov
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: advisor,agent-skill,bm25,claude-code,claude-skill,fastembed,llm,rag,semantic-search,transcripts,youtube,yt-dlp
|
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
38
|
+
Classifier: Programming Language :: Python :: 3
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
42
|
+
Classifier: Topic :: Multimedia :: Video
|
|
43
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
44
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
45
|
+
Classifier: Topic :: Utilities
|
|
46
|
+
Requires-Python: >=3.11
|
|
47
|
+
Requires-Dist: anthropic>=0.34.0
|
|
48
|
+
Requires-Dist: click>=8.1
|
|
49
|
+
Requires-Dist: fastembed>=0.3.0
|
|
50
|
+
Requires-Dist: jinja2>=3.1
|
|
51
|
+
Requires-Dist: numpy>=1.26
|
|
52
|
+
Requires-Dist: pyyaml>=6.0
|
|
53
|
+
Requires-Dist: rank-bm25>=0.2.2
|
|
54
|
+
Requires-Dist: tqdm>=4.66
|
|
55
|
+
Requires-Dist: youtube-transcript-api>=0.6.2
|
|
56
|
+
Requires-Dist: yt-dlp>=2024.5.0
|
|
57
|
+
Provides-Extra: dev
|
|
58
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
59
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
60
|
+
Requires-Dist: vcrpy>=6.0; extra == 'dev'
|
|
61
|
+
Provides-Extra: multilingual
|
|
62
|
+
Requires-Dist: fastembed[multilingual]; extra == 'multilingual'
|
|
63
|
+
Provides-Extra: whisper
|
|
64
|
+
Requires-Dist: faster-whisper>=1.0.0; extra == 'whisper'
|
|
65
|
+
Description-Content-Type: text/markdown
|
|
66
|
+
|
|
67
|
+
<p align="center">
|
|
68
|
+
<img src="docs/logo.png" alt="youtube-advisor" width="180" />
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
<h1 align="center">youtube-advisor</h1>
|
|
72
|
+
|
|
73
|
+
<p align="center">
|
|
74
|
+
<strong>Turn any YouTube channel into an AI assistant skill that answers questions with verbatim quotes and timestamped video links.</strong>
|
|
75
|
+
</p>
|
|
76
|
+
|
|
77
|
+
<p align="center">
|
|
78
|
+
<a href="https://github.com/AlexanderAbramovPav/youtube-advisor/stargazers"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/AlexanderAbramovPav/youtube-advisor?style=flat-square&label=Stars&logo=github&color=lightgrey" /></a>
|
|
79
|
+
<a href="https://github.com/AlexanderAbramovPav/youtube-advisor/releases/latest"><img alt="Latest release" src="https://img.shields.io/github/v/release/AlexanderAbramovPav/youtube-advisor?style=flat-square&label=Release&color=lightgrey" /></a>
|
|
80
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-lightgrey?style=flat-square" /></a>
|
|
81
|
+
<img alt="100% Local" src="https://img.shields.io/badge/100%25-Local-lightgrey?style=flat-square" />
|
|
82
|
+
<img alt="No API key" src="https://img.shields.io/badge/No_API_Key-required-lightgrey?style=flat-square" />
|
|
83
|
+
</p>
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## What it feels like
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
You: build an advisor on @ycombinator,
|
|
91
|
+
last 200 videos, hiring + fundraising
|
|
92
|
+
|
|
93
|
+
AI: ✓ Resolving @ycombinator (200 videos)
|
|
94
|
+
✓ Fetching transcripts (3 min)
|
|
95
|
+
✓ Indexing + embedding
|
|
96
|
+
✓ Advisor ready: /yc-advisor
|
|
97
|
+
|
|
98
|
+
You: /yc-advisor how should I think about hiring my first engineer?
|
|
99
|
+
AI: → answer with quoted videos and timestamps
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Install
|
|
103
|
+
|
|
104
|
+
Paste this in your AI chat (Claude Code, Cursor, Codex CLI, etc.):
|
|
105
|
+
|
|
106
|
+
> Install youtube-advisor for me. The repo is https://github.com/AlexanderAbramovPav/youtube-advisor.
|
|
107
|
+
|
|
108
|
+
The AI clones, runs `scripts/install.sh`, checks `ffmpeg` and `uv`, sets up the venv. You walk away.
|
|
109
|
+
|
|
110
|
+
## Use it
|
|
111
|
+
|
|
112
|
+
**Create an advisor.** Drop a channel URL or handle in chat with a one-sentence intent:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
build an advisor on @ycombinator from the last 200 videos,
|
|
116
|
+
focused on hiring and fundraising
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
make an advisor on @lexfridman, interviews from 2024 onwards
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The assistant resolves the channel, fetches transcripts, builds indices, drafts the advisor's voice, and runs a self-check. No flags, no paths, no shell. You get a new slash command like `/yc-advisor`.
|
|
124
|
+
|
|
125
|
+
**Ask the advisor.**
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
/yc-advisor how should I think about hiring my first engineer?
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Every answer comes back with verbatim quotes and clickable timestamps linking to the exact second of the source.
|
|
132
|
+
|
|
133
|
+
**Refresh later.** One sentence:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
refresh @ycombinator — check for new videos this week
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The assistant replays your original selection filter, fetches only what's new, re-indexes the delta, and tells you what changed.
|
|
140
|
+
|
|
141
|
+
## Why
|
|
142
|
+
|
|
143
|
+
- **Local-first.** Transcripts and indices live on your disk. No SaaS account, no per-query fees, no vendor that can take your corpus offline.
|
|
144
|
+
- **Verbatim quotes with timestamps.** Every answer is grounded in real transcript text and links to `youtube.com/watch?v=ID&t=SECONDS` — click and the video opens at that exact second.
|
|
145
|
+
- **Uses your AI's brain.** Skill drafting and answering run through whatever assistant you're already using — nothing extra to configure.
|
|
146
|
+
- **Free captions when available; local Whisper when not.** A three-tier cascade keeps cost near zero and falls back to on-device transcription only when YouTube has none.
|
|
147
|
+
- **Incremental updates that respect your filter.** Your original selection (channel + date range + title filters + max count) is saved and replayed on every refresh.
|
|
148
|
+
|
|
149
|
+
## What an answer looks like
|
|
150
|
+
|
|
151
|
+
> *"The scariest fundraising stories are the ones where the founder spends six months on an 'almost-yes' from an investor who eventually just ghosts."*
|
|
152
|
+
>
|
|
153
|
+
> — [Dalton & Michael: Fundraising Mistakes (2024-03-12), 14:22](https://youtube.com/watch?v=abc123&t=862)
|
|
154
|
+
|
|
155
|
+
Each citation is a real line from a real video, anchored to the second. Click through and verify.
|
|
156
|
+
|
|
157
|
+
## Limitations
|
|
158
|
+
|
|
159
|
+
- **One channel per advisor.** Multi-channel rollups ("YC + Naval + a16z combined") are planned for v0.2.
|
|
160
|
+
- **Whisper fallback is CPU-bound.** Videos without YT captions fall back to local Whisper — roughly 1 hour of compute per 1 hour of audio on Apple Silicon. The assistant warns you and asks before going that route.
|
|
161
|
+
- **YouTube anti-bot.** Defaults (1–5s randomized sleep, exponential-backoff retries on 429) handle most cases. On persistent blocks the assistant will offer to use cookies from your logged-in browser.
|
|
162
|
+
|
|
163
|
+
## Works with other AI tools
|
|
164
|
+
|
|
165
|
+
`AGENTS.md` is a tool-agnostic mirror of `SKILL.md`. Wire it into whichever tool you use:
|
|
166
|
+
|
|
167
|
+
| Your tool | Where to point it | How to invoke |
|
|
168
|
+
| ------------------ | ------------------------------------------------------------------------------ | ---------------------------------------- |
|
|
169
|
+
| Claude Code | clone into `~/.claude/skills/youtube-advisor/` | `/youtube-advisor <request>` |
|
|
170
|
+
| OpenAI Codex CLI | clone anywhere, place `AGENTS.md` at `~/.codex/AGENTS.md` (or project root) | "build me an advisor on `<channel>`" |
|
|
171
|
+
| Cursor | clone anywhere, copy `AGENTS.md` to `.cursor/rules/youtube-advisor.md` | `@youtube-advisor` or natural language |
|
|
172
|
+
| Continue.dev | clone anywhere, register `youtube-advisor` as a custom slash command | `/youtube-advisor <request>` |
|
|
173
|
+
| Aider | clone anywhere, `aider --read <install-dir>/AGENTS.md` | natural language in chat |
|
|
174
|
+
| Goose (Block) | clone anywhere, add as a shell-command extension | mention youtube-advisor in chat |
|
|
175
|
+
| No AI at all | clone anywhere | `youtube-advisor bootstrap --channel @… --out …` |
|
|
176
|
+
|
|
177
|
+
<details>
|
|
178
|
+
<summary><strong>Advanced — for CI and scripting</strong></summary>
|
|
179
|
+
|
|
180
|
+
Everything below is for power users running outside an AI chat (CI, cron, scripts). **You almost never need this.**
|
|
181
|
+
|
|
182
|
+
### Manual install
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
git clone https://github.com/AlexanderAbramovPav/youtube-advisor ~/.claude/skills/youtube-advisor
|
|
186
|
+
cd ~/.claude/skills/youtube-advisor && bash scripts/install.sh
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### CLI
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Bootstrap
|
|
193
|
+
youtube-advisor bootstrap \
|
|
194
|
+
--channel @ycombinator \
|
|
195
|
+
--since 2022-01-01 \
|
|
196
|
+
--max 200 \
|
|
197
|
+
--title-include "Founder Stories|How to" \
|
|
198
|
+
--title-exclude "shorts|#shorts" \
|
|
199
|
+
--out ~/.claude/skills/yc-advisor \
|
|
200
|
+
--yes
|
|
201
|
+
|
|
202
|
+
# Update (replays the saved selection filter)
|
|
203
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --yes
|
|
204
|
+
|
|
205
|
+
# Update — override date, reindex only, or run regression evals
|
|
206
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --since 2026-01-01 --yes
|
|
207
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --reindex-only
|
|
208
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --run-evals --yes
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`youtube-advisor bootstrap --help` and `youtube-advisor update --help` print the full flag list.
|
|
212
|
+
|
|
213
|
+
### Bypassing YT anti-bot with browser cookies
|
|
214
|
+
|
|
215
|
+
When unauthenticated channel-resolution gets 429-blocked, pass cookies from a logged-in browser. yt-dlp reads them straight from the browser profile — no copy-paste:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
youtube-advisor bootstrap --channel @ycombinator --out ~/.claude/skills/yc-advisor \
|
|
219
|
+
--cookies-from-browser chrome --yes
|
|
220
|
+
|
|
221
|
+
# Or a Netscape-format cookies.txt:
|
|
222
|
+
youtube-advisor bootstrap --channel @ycombinator --out ~/.claude/skills/yc-advisor \
|
|
223
|
+
--cookies ~/secrets/yt-cookies.txt --yes
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Resolution order: explicit flag → `YOUTUBE_ADVISOR_COOKIES_BROWSER` / `YOUTUBE_ADVISOR_COOKIES_FILE` env → `~/.config/youtube-advisor/cookies.txt` if present → none. With cookies set the captions pool stays at concurrency 8; without them it drops to 2 + per-call jitter so YT is less likely to block you.
|
|
227
|
+
|
|
228
|
+
### Vendoring `_lib`
|
|
229
|
+
|
|
230
|
+
`youtube-advisor bootstrap --vendor` copies the `youtube_advisor` Python package into the emitted advisor's `scripts/_lib/`. Useful if you want the advisor directory to be fully portable (pushed to a separate Git repo and cloned elsewhere without a Python install of `youtube-advisor`).
|
|
231
|
+
|
|
232
|
+
### Eval-driven regression detection
|
|
233
|
+
|
|
234
|
+
`youtube-advisor update --advisor <path> --run-evals` reruns the channel's generated benchmark after sync and prompts to roll back if pass rate dropped.
|
|
235
|
+
|
|
236
|
+
</details>
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
[MIT](./LICENSE) — © 2026 Alexander Abramov.
|
|
241
|
+
|
|
242
|
+
Runtime dependencies (yt-dlp, youtube-transcript-api, fastembed, faster-whisper, rank-bm25, ffmpeg, scriba) are installed locally, not vendored. Their licenses are catalogued in [`THIRD_PARTY_LICENSES.md`](./THIRD_PARTY_LICENSES.md).
|
|
243
|
+
|
|
244
|
+
## Acknowledgments
|
|
245
|
+
|
|
246
|
+
This tool is glue around several excellent OSS projects:
|
|
247
|
+
|
|
248
|
+
- [**yt-dlp**](https://github.com/yt-dlp/yt-dlp) — channel resolution, caption download, audio extraction.
|
|
249
|
+
- [**youtube-transcript-api**](https://github.com/jdepoix/youtube-transcript-api) — Jonas Depoix — Tier 1 captions fetcher.
|
|
250
|
+
- [**fastembed**](https://github.com/qdrant/fastembed) — Qdrant — local embedding inference with `bge-small-en-v1.5` (BAAI).
|
|
251
|
+
- [**rank-bm25**](https://github.com/dorianbrown/rank_bm25) — Dorian Brown — BM25 ranking.
|
|
252
|
+
- [**faster-whisper**](https://github.com/SYSTRAN/faster-whisper) — SYSTRAN — local ASR fallback.
|
|
253
|
+
- [**scriba**](https://github.com/AlexanderAbramovPav/scriba) — sibling skill — alternative Whisper transcription backend.
|
|
254
|
+
- [**uv**](https://github.com/astral-sh/uv) (Astral) for env setup, and [`ffmpeg`](https://ffmpeg.org/) for audio extraction.
|
|
255
|
+
- Conceptual lineage: [yc-avisor](https://github.com/AlexanderAbramovPav/cowork) — the hand-rolled YC-channel-specific predecessor.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/logo.png" alt="youtube-advisor" width="180" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">youtube-advisor</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Turn any YouTube channel into an AI assistant skill that answers questions with verbatim quotes and timestamped video links.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/AlexanderAbramovPav/youtube-advisor/stargazers"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/AlexanderAbramovPav/youtube-advisor?style=flat-square&label=Stars&logo=github&color=lightgrey" /></a>
|
|
13
|
+
<a href="https://github.com/AlexanderAbramovPav/youtube-advisor/releases/latest"><img alt="Latest release" src="https://img.shields.io/github/v/release/AlexanderAbramovPav/youtube-advisor?style=flat-square&label=Release&color=lightgrey" /></a>
|
|
14
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-lightgrey?style=flat-square" /></a>
|
|
15
|
+
<img alt="100% Local" src="https://img.shields.io/badge/100%25-Local-lightgrey?style=flat-square" />
|
|
16
|
+
<img alt="No API key" src="https://img.shields.io/badge/No_API_Key-required-lightgrey?style=flat-square" />
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What it feels like
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
You: build an advisor on @ycombinator,
|
|
25
|
+
last 200 videos, hiring + fundraising
|
|
26
|
+
|
|
27
|
+
AI: ✓ Resolving @ycombinator (200 videos)
|
|
28
|
+
✓ Fetching transcripts (3 min)
|
|
29
|
+
✓ Indexing + embedding
|
|
30
|
+
✓ Advisor ready: /yc-advisor
|
|
31
|
+
|
|
32
|
+
You: /yc-advisor how should I think about hiring my first engineer?
|
|
33
|
+
AI: → answer with quoted videos and timestamps
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
Paste this in your AI chat (Claude Code, Cursor, Codex CLI, etc.):
|
|
39
|
+
|
|
40
|
+
> Install youtube-advisor for me. The repo is https://github.com/AlexanderAbramovPav/youtube-advisor.
|
|
41
|
+
|
|
42
|
+
The AI clones, runs `scripts/install.sh`, checks `ffmpeg` and `uv`, sets up the venv. You walk away.
|
|
43
|
+
|
|
44
|
+
## Use it
|
|
45
|
+
|
|
46
|
+
**Create an advisor.** Drop a channel URL or handle in chat with a one-sentence intent:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
build an advisor on @ycombinator from the last 200 videos,
|
|
50
|
+
focused on hiring and fundraising
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
make an advisor on @lexfridman, interviews from 2024 onwards
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The assistant resolves the channel, fetches transcripts, builds indices, drafts the advisor's voice, and runs a self-check. No flags, no paths, no shell. You get a new slash command like `/yc-advisor`.
|
|
58
|
+
|
|
59
|
+
**Ask the advisor.**
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
/yc-advisor how should I think about hiring my first engineer?
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Every answer comes back with verbatim quotes and clickable timestamps linking to the exact second of the source.
|
|
66
|
+
|
|
67
|
+
**Refresh later.** One sentence:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
refresh @ycombinator — check for new videos this week
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The assistant replays your original selection filter, fetches only what's new, re-indexes the delta, and tells you what changed.
|
|
74
|
+
|
|
75
|
+
## Why
|
|
76
|
+
|
|
77
|
+
- **Local-first.** Transcripts and indices live on your disk. No SaaS account, no per-query fees, no vendor that can take your corpus offline.
|
|
78
|
+
- **Verbatim quotes with timestamps.** Every answer is grounded in real transcript text and links to `youtube.com/watch?v=ID&t=SECONDS` — click and the video opens at that exact second.
|
|
79
|
+
- **Uses your AI's brain.** Skill drafting and answering run through whatever assistant you're already using — nothing extra to configure.
|
|
80
|
+
- **Free captions when available; local Whisper when not.** A three-tier cascade keeps cost near zero and falls back to on-device transcription only when YouTube has none.
|
|
81
|
+
- **Incremental updates that respect your filter.** Your original selection (channel + date range + title filters + max count) is saved and replayed on every refresh.
|
|
82
|
+
|
|
83
|
+
## What an answer looks like
|
|
84
|
+
|
|
85
|
+
> *"The scariest fundraising stories are the ones where the founder spends six months on an 'almost-yes' from an investor who eventually just ghosts."*
|
|
86
|
+
>
|
|
87
|
+
> — [Dalton & Michael: Fundraising Mistakes (2024-03-12), 14:22](https://youtube.com/watch?v=abc123&t=862)
|
|
88
|
+
|
|
89
|
+
Each citation is a real line from a real video, anchored to the second. Click through and verify.
|
|
90
|
+
|
|
91
|
+
## Limitations
|
|
92
|
+
|
|
93
|
+
- **One channel per advisor.** Multi-channel rollups ("YC + Naval + a16z combined") are planned for v0.2.
|
|
94
|
+
- **Whisper fallback is CPU-bound.** Videos without YT captions fall back to local Whisper — roughly 1 hour of compute per 1 hour of audio on Apple Silicon. The assistant warns you and asks before going that route.
|
|
95
|
+
- **YouTube anti-bot.** Defaults (1–5s randomized sleep, exponential-backoff retries on 429) handle most cases. On persistent blocks the assistant will offer to use cookies from your logged-in browser.
|
|
96
|
+
|
|
97
|
+
## Works with other AI tools
|
|
98
|
+
|
|
99
|
+
`AGENTS.md` is a tool-agnostic mirror of `SKILL.md`. Wire it into whichever tool you use:
|
|
100
|
+
|
|
101
|
+
| Your tool | Where to point it | How to invoke |
|
|
102
|
+
| ------------------ | ------------------------------------------------------------------------------ | ---------------------------------------- |
|
|
103
|
+
| Claude Code | clone into `~/.claude/skills/youtube-advisor/` | `/youtube-advisor <request>` |
|
|
104
|
+
| OpenAI Codex CLI | clone anywhere, place `AGENTS.md` at `~/.codex/AGENTS.md` (or project root) | "build me an advisor on `<channel>`" |
|
|
105
|
+
| Cursor | clone anywhere, copy `AGENTS.md` to `.cursor/rules/youtube-advisor.md` | `@youtube-advisor` or natural language |
|
|
106
|
+
| Continue.dev | clone anywhere, register `youtube-advisor` as a custom slash command | `/youtube-advisor <request>` |
|
|
107
|
+
| Aider | clone anywhere, `aider --read <install-dir>/AGENTS.md` | natural language in chat |
|
|
108
|
+
| Goose (Block) | clone anywhere, add as a shell-command extension | mention youtube-advisor in chat |
|
|
109
|
+
| No AI at all | clone anywhere | `youtube-advisor bootstrap --channel @… --out …` |
|
|
110
|
+
|
|
111
|
+
<details>
|
|
112
|
+
<summary><strong>Advanced — for CI and scripting</strong></summary>
|
|
113
|
+
|
|
114
|
+
Everything below is for power users running outside an AI chat (CI, cron, scripts). **You almost never need this.**
|
|
115
|
+
|
|
116
|
+
### Manual install
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
git clone https://github.com/AlexanderAbramovPav/youtube-advisor ~/.claude/skills/youtube-advisor
|
|
120
|
+
cd ~/.claude/skills/youtube-advisor && bash scripts/install.sh
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### CLI
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Bootstrap
|
|
127
|
+
youtube-advisor bootstrap \
|
|
128
|
+
--channel @ycombinator \
|
|
129
|
+
--since 2022-01-01 \
|
|
130
|
+
--max 200 \
|
|
131
|
+
--title-include "Founder Stories|How to" \
|
|
132
|
+
--title-exclude "shorts|#shorts" \
|
|
133
|
+
--out ~/.claude/skills/yc-advisor \
|
|
134
|
+
--yes
|
|
135
|
+
|
|
136
|
+
# Update (replays the saved selection filter)
|
|
137
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --yes
|
|
138
|
+
|
|
139
|
+
# Update — override date, reindex only, or run regression evals
|
|
140
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --since 2026-01-01 --yes
|
|
141
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --reindex-only
|
|
142
|
+
youtube-advisor update --advisor ~/.claude/skills/yc-advisor --run-evals --yes
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`youtube-advisor bootstrap --help` and `youtube-advisor update --help` print the full flag list.
|
|
146
|
+
|
|
147
|
+
### Bypassing YT anti-bot with browser cookies
|
|
148
|
+
|
|
149
|
+
When unauthenticated channel-resolution gets 429-blocked, pass cookies from a logged-in browser. yt-dlp reads them straight from the browser profile — no copy-paste:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
youtube-advisor bootstrap --channel @ycombinator --out ~/.claude/skills/yc-advisor \
|
|
153
|
+
--cookies-from-browser chrome --yes
|
|
154
|
+
|
|
155
|
+
# Or a Netscape-format cookies.txt:
|
|
156
|
+
youtube-advisor bootstrap --channel @ycombinator --out ~/.claude/skills/yc-advisor \
|
|
157
|
+
--cookies ~/secrets/yt-cookies.txt --yes
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Resolution order: explicit flag → `YOUTUBE_ADVISOR_COOKIES_BROWSER` / `YOUTUBE_ADVISOR_COOKIES_FILE` env → `~/.config/youtube-advisor/cookies.txt` if present → none. With cookies set the captions pool stays at concurrency 8; without them it drops to 2 + per-call jitter so YT is less likely to block you.
|
|
161
|
+
|
|
162
|
+
### Vendoring `_lib`
|
|
163
|
+
|
|
164
|
+
`youtube-advisor bootstrap --vendor` copies the `youtube_advisor` Python package into the emitted advisor's `scripts/_lib/`. Useful if you want the advisor directory to be fully portable (pushed to a separate Git repo and cloned elsewhere without a Python install of `youtube-advisor`).
|
|
165
|
+
|
|
166
|
+
### Eval-driven regression detection
|
|
167
|
+
|
|
168
|
+
`youtube-advisor update --advisor <path> --run-evals` reruns the channel's generated benchmark after sync and prompts to roll back if pass rate dropped.
|
|
169
|
+
|
|
170
|
+
</details>
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
[MIT](./LICENSE) — © 2026 Alexander Abramov.
|
|
175
|
+
|
|
176
|
+
Runtime dependencies (yt-dlp, youtube-transcript-api, fastembed, faster-whisper, rank-bm25, ffmpeg, scriba) are installed locally, not vendored. Their licenses are catalogued in [`THIRD_PARTY_LICENSES.md`](./THIRD_PARTY_LICENSES.md).
|
|
177
|
+
|
|
178
|
+
## Acknowledgments
|
|
179
|
+
|
|
180
|
+
This tool is glue around several excellent OSS projects:
|
|
181
|
+
|
|
182
|
+
- [**yt-dlp**](https://github.com/yt-dlp/yt-dlp) — channel resolution, caption download, audio extraction.
|
|
183
|
+
- [**youtube-transcript-api**](https://github.com/jdepoix/youtube-transcript-api) — Jonas Depoix — Tier 1 captions fetcher.
|
|
184
|
+
- [**fastembed**](https://github.com/qdrant/fastembed) — Qdrant — local embedding inference with `bge-small-en-v1.5` (BAAI).
|
|
185
|
+
- [**rank-bm25**](https://github.com/dorianbrown/rank_bm25) — Dorian Brown — BM25 ranking.
|
|
186
|
+
- [**faster-whisper**](https://github.com/SYSTRAN/faster-whisper) — SYSTRAN — local ASR fallback.
|
|
187
|
+
- [**scriba**](https://github.com/AlexanderAbramovPav/scriba) — sibling skill — alternative Whisper transcription backend.
|
|
188
|
+
- [**uv**](https://github.com/astral-sh/uv) (Astral) for env setup, and [`ffmpeg`](https://ffmpeg.org/) for audio extraction.
|
|
189
|
+
- Conceptual lineage: [yc-avisor](https://github.com/AlexanderAbramovPav/cowork) — the hand-rolled YC-channel-specific predecessor.
|