本文へ移動
cccskills
無料GitHub で公開

youtube-publish

Публикует готовый контент на личный YouTube-канал Антона [аккаунт]: вычерпывает новое из NotebookLM и очереди, рендерит аудио в видео, пишет описание с фрагментом расшифровки для SEO и авторским блоком Антона, грузит и читает статус обратно. Триггеры: /youtube-publish, /yt, выложи на ютуб, залей на youtube, что ждёт выгрузки. НЕ /teach-podcast и не /notebooklm — те ПРОИЗВОДЯТ, этот ПУБЛИКУЕТ.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md20.7 KB
  • routine-seed.md4.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

/youtube-publish — контент на личный канал Антона

🧒 Доклад Антону кончается блоком «Простыми словами» ([[eli5-always]]). Описания видео — без ELI5, у них свой голос.

Родился 21.09.2026 из голосовой Антона (tg:-[id], 08:34 UTC). Дословно: «Публиковать разный контент на личный YouTube-канал. Один из основных источников контента сейчас — NotebookLM... Как только появляется новый материал из NotebookLM, его нужно выкладывать на YouTube... Делать качественное описание к видео: что это за видео, о чём оно, зачем создано. Добавлять небольшой транскрипт или фрагмент транскрипта для лучшего SEO/GEO. Сделать так, чтобы видео легко находилось через поиск. Обязательно добавлять авторский контекст от Антона.»

Цель контента (его слова): обучение Антона · подготовка к трудоустройству в LLM-компанию · публичный YouTube-след вокруг LLM/AI-тем.

Склейка с другими скиллами (он прямо просил «будет склеиваться»): контракт односторонний. Производители (/teach-podcast, /notebooklm, /episode, любая будущая труба) кладут строку в очередь $OBSIDIAN_VAULT/05-Resources/NotebookLM/_youtube-queue.md. Этот скилл вычерпывает её и больше ничего от них не требует. Производитель забыл строку — не беда: движок делает и свободный скан папок артефактов, файл на диске потерять нельзя (замер 21.09: очередь знала 14 файлов, на диске лежало 35).

Канал — доказан, не угадан

[аккаунт] · UCa_lk_0LTagC9tI6f9NRF_w · «Tony» · 305 подписчиков · 75 видео · с 18.03.2011. Три независимые улики (21.09.2026):

  1. YouTube Data API v3 по id из истории браузера вернул title/customUrl/статистику.
  2. browser_history.db: Антон сам открывал Студию этого канала 30.08 и 02.09 из Firefox-профиля m26xxxkf.anton-clean — значит и канал его, и живой логин лежит именно там.
  3. На канале уже висят его ролики «моя работа с Claude Code» (30–31.08.2026) — та же тематика.

⚠️ Другого личного канала не искали шире истории браузера. Появится второй — уточнить у Антона, а не выбирать самому.

⛔ Законы

  1. Описание несёт ЧЕТЫРЕ обязательных куска (прямой список Антона): (а) о чём видео; (б) зачем создано; (в) фрагмент расшифровки для поиска; (г) авторский контекст от него. Нет любого из четырёх — описание бракованное, публиковать нельзя.
  2. Авторский блок пишется от ПЕРВОГО лица Антона и называет Mycroft. Его формулировка: «Это видео от Антона, оно сгенерировано моим кофаундером Mycroft». Раскрытие ИИ живёт внутри этого блока — плашки «AI-generated» отдельно не ставим (§3.3, DR-701: планка = review control + названное ответственное лицо, а лицо здесь Антон).
  3. Публичность по умолчанию, приватное не едет. Гейт privacy_scan перед каждой загрузкой: почта, имена рекрутёров, вилки денег из переписки, секреты. Сработал — видео пропускается, строка в леджер blocked-privacy, чиним руками. Наш собственный calendly/WhatsApp/github — не утечка, это подпись (§1.1).
  4. Подпись обязательна. Футер = блоки C+E из $IMPORTS_ROOT/content-factory/_STYLE-footer.md плюс Linktree и github.com/tonydzi. YouTube = публичная поверхность, карве-аутов нет. EN-описание НЕ упоминает RU-каналы (правило [коллега] 07.07).
  5. Язык описания = язык дорожки. Суффикс -ru / -en в имени файла — истина. RU-эпизод с английским описанием = брак: YouTube так и проиндексирует.
  6. Находимость строится тремя рычагами, не тегами одними: (1) субтитры из расшифровки (captions.insert) — YouTube индексирует их текст целиком и это сильнее любых тегов для аудио-контента; (2) defaultLanguage/defaultAudioLanguage проставлены; (3) первые три тега продублированы хэштегами — они показываются над заголовком.
  7. Готово = прочитано обратно. После загрузки движок сам делает videos.list и печатает реальный privacyStatus. Код ответа 200 доказательством публикации не является (§4.3-бис).
  8. Выдумывать нельзя. Описание собирается из очереди, пакета урока и расшифровки. Нет данных — пишем короче, а не сочиняем содержание, которого в видео нет.
  9. Суточный потолок 5 видео — не вкус, а арифметика квоты: 1600 (videos.insert) + 400 (captions.insert) + 1 (videos.list) ≈ 2001 единица, суточная квота проекта 10 000. Потолок зашит в DAILY_CAP и проверяется регрессом.
  10. Публикуем только вычитанное. run по умолчанию берёт ТОЛЬКО строки очереди — у них человеческий заголовок. Файлы свободного скана видны в scan, но наружу без флага --include-unqueued не идут: заголовок «Hedge 01 inside», собранный из имени файла, на публичном канале Антона выглядит браком. Нужен нормальный заголовок — строку пишет производитель (/teach-podcast), а не этот скилл на глаз.
  11. Серия выходит по номерам, а не по дате файла. «(урок 3)» в заголовке — ключ сортировки. Урок 15 сделан позже урока 1, но и выйти должен позже.

Рельсы: две, и выбор между ними ЗАМЕРЯЕТСЯ

Рельса A — API (основная, безлюдная)

videos.insert resumable + captions.insert. Всё ставится одним вызовом: заголовок, описание, теги, категория 27 (Education), язык, видимость. Только эта рельса умеет работать ночью без человека.

⚠️ РИСК, КОТОРЫЙ ОБЯЗАН БЫТЬ ЗАМЕРЕН, А НЕ ПРЕДПОЛОЖЕН. У GCP-проектов, не прошедших аудит YouTube API, загруженные через API видео могут запираться в private без возможности открыть их руками. Это заявленное поведение платформы, и оно ломает всю цель («публичный след»). Поэтому run по умолчанию идёт канарейкой --limit 1 и сразу читает статус обратно:

  • privacyStatus == public → рельса A рабочая, дальше можно пачкой;
  • иначе → движок сам останавливается с кодом 2 и печатает вердикт; переходим на рельсу B.

⛔ До канарейки запрещено говорить «рельса A работает» — это claim (§5.4).

Рельса B — браузер (фолбэк и первый боевой заход)

Firefox, профиль m26xxxkf.anton-clean (там живой логин канала), studio.youtube.com. Команда manifest печатает и кладёт готовый пакет: путь к mp4 + заголовок + описание + теги

  • видимость. Дальше Create → Upload videos → перетащить mp4 → вставить поля из манифеста. Ban-риска нет: это собственный канал Антона, а не чужая площадка.

Шаг 0. RECALL и состояние

python ~/.claude/scripts/youtube_publish.py scan      # что ждёт, сколько уже ушло сегодня
python ~/.claude/scripts/youtube_publish.py ledger    # что уже на канале
python ~/.claude/scripts/youtube_publish.py auth check # жива ли рельса A

Леджер ~/.claude/state/youtube_ledger.jsonl — единственный источник «что уже выложено». Статус в очереди волта — подсказка человеку: очередь под Syncthing, её правят три узла, у неё уже есть sync-conflict-копии. Сторож не живёт в том, что сторожит ([[watchdog-must-verify-the-item]]).

Шаг 1. Посмотреть описание ГЛАЗАМИ до публикации

python ~/.claude/scripts/youtube_publish.py meta <имя файла>

Печатает ровно то, что увидит зритель, плюс счётчики лимитов (заголовок/100, описание/5000, теги/500) и вердикт гейта приватности. Первый эпизод серии смотрим глазами всегда — дальше шаблон уже проверен и можно пачкой.

Сомнение по вкусу текста → /taste-check <файл описания>.

Шаг 2. Рендер (аудио → видео)

YouTube не принимает голый .m4a, нужен видеоконтейнер.

python ~/.claude/scripts/youtube_publish.py render <имя файла>

Делает обложку 1920×1080 (тёмная карточка: строка серии, заголовок в 5 строк, [аккаунт], Palo Alto AI Research Lab · NotebookLM) и склеивает с дорожкой: h264, 2 к/с, aac 192k, +faststart. Замер 21.09: эпизод 18 минут → 26,5 МБ за 2 минуты на хабе.

Шаг 3. Заливка

python ~/.claude/scripts/youtube_publish.py run --limit 1    # КАНАРЕЙКА, первый раз всегда так
python ~/.claude/scripts/youtube_publish.py run --limit 5    # рабочий заход после зелёной канарейки
python ~/.claude/scripts/youtube_publish.py run --dry-run    # посмотреть план без действий
python ~/.claude/scripts/youtube_publish.py run --include-unqueued   # редко: и файлы без строки

Порядок внутри: гейт приватности → рендер → субтитры (faster-whisper локально, 0 токенов) → загрузка → чтение статуса обратно → строка в леджер → отметка в очереди (best-effort). Падение на любом шаге пишет причину в леджер и не помечает файл сделанным: упавший эпизод остаётся в очереди, иначе он теряется молча.

Рельса A мертва или заперла видео → рельса B:

python ~/.claude/scripts/youtube_publish.py manifest --limit 5

Шаг 4. Проверка (§4.3-бис, второй заход другим методом)

  1. verify <videoId> — privacyStatus, uploadStatus, причина отказа, если есть.
  2. Открыть https://youtu.be/<id> и посмотреть глазами: звук идёт, обложка та, описание не обрезано на середине блока.
  3. Через сутки: видео находится поиском по своему заголовку? Нет — значит находимость не построена, и это отдельная починка, а не «ну бывает».
  4. Итог пишется парой: «проверено: … · НЕ проверено: … (почему)».

Шаг 5. Учёт и связи (тем же заходом)

  1. Леджер пишется движком сам.
  2. Строка в очереди → «выложено <дата> <ссылка>» (движок делает best-effort).
  3. _teach-curriculum.md: статус урока → «на YouTube» + ссылка.
  4. Ссылка уходит обратно в учебный контур: в шпаргалку /interview-prep того звонка, к которому урок, — строка «Подкаст: <ссылка>».
  5. Контент-майнер ([[content-miner-reflex]]): вышел эпизод — черновик тизера в воронку. Один эпизод = один тизер, не веер (§1.5 «спам ≠ громкость»).
  6. Вердикт о скилле одной строкой: 🔧 обновляю / 📝 обновлю не сейчас / ✅ не надо, с причиной (§9.3-бис). Рутина судит ещё и собственную инструкцию (§9.3-бис поправка 13.09).

Рутина

youtube-publish-drip — ночное окно 23:00–06:00 Лиссабон (§4.6), раз в сутки, --limit 5. Почему ежедневно, а не «раз в 2–3 дня», как допускал Антон: суточная квота всё равно режет до 5 видео, а ежедневный мелкий заход ровнее ложится на производство (/teach-podcast делает 1–5 эпизодов в день). Накопилось больше — само растянется на несколько ночей. ⛔ Рутина НЕ поднимается из сессии, порождённой scheduled-task (§9.2): сид кладётся в spawn_queue.py, живая сессия его поднимает. Темп режем по §4.5-тер, если хаб начнёт тормозить.

Грабли, оплаченные при рождении (21.09.2026)

  1. Порядок чисток в описании. Черновики очереди кончаются фразой «Контакты и CTA — из _STYLE-footer.md». Снимать надо СНАЧАЛА бэктики, ПОТОМ фразу: иначе точка внутри _STYLE-footer.md обрывает замену и в публичное описание уезжает хвост «md.». Поймано регрессом test_internal_vault_paths_never_leak`, который на этом краснел.
  2. Тайм-коды в расшифровке. Дорожки NotebookLM идут с [00:03] на каждой фразе. В описании это мусор: YouTube индексирует слова, а не скобки. Движок их снимает.
  3. Расшифровка машинная и с опечатками («менажмент», «искусном интеллекте»). Правим не текст, а честность: фрагмент помечен «машинная, с опечатками». Вычитывать чужую ASR-дорожку ради описания — работа не по цене.
  4. Очередь знает не всё. 14 строк в очереди против 35 файлов на диске. Поэтому скан свободный, а не только по очереди.
  5. Голый .m4a YouTube не берёт — всегда рендер в mp4.

Потребители

  • Антон — /yt, «выложи на ютуб», «что ждёт выгрузки».
  • /teach-podcast Шаг 6.3 — кладёт строку в _youtube-queue.md; этот скилл её вычерпывает.
  • /notebooklm — любой артефакт, который не стыдно показать миру, идёт той же дорогой.
  • рутина youtube-publish-drip — ночной вычерп.

Двери и файлы

  • Движок: ~/.claude/scripts/youtube_publish.py (док внутри файла, §5.8).
  • Регресс: ~/.claude/scripts/_test_youtube_publish.py — 28 проверок, kill-list в шапке.
  • Леджер: ~/.claude/state/youtube_ledger.jsonl.
  • Рендер и манифест: ~/.claude/state/youtube_render/.
  • Очередь: $OBSIDIAN_VAULT/05-Resources/NotebookLM/_youtube-queue.md.
  • Токен рельсы A: <secrets>/youtube_token_tonydzz.json (в волт и в always-loaded не кладём, §3.4).

Канон: CLAUDE.md §9.13 (учим Антона подкастом), §1.1 (подпись в каждом касании), §3.3 (голос и раскрытие), §3.2 (публичные каналы), §5.7 (shadow-first), §4.3-бис (готово = второй заход). Память: [[teach-anton-by-podcast-default]], [[youtube-publish-channel-and-rails]], [[everything-becomes-content]], [[outbound-signature]].

<!--kit-footer-->

Like this skill? It is one of 100 in second-brain-starter-kit: the second brain we built for ourselves and run every day at Palo Alto AI Research Lab. Install the whole set with npx skills add tonydzi/second-brain-starter-kit. Everything is open source and free, so take what you need.

Flagships worth a look on their own: secondop-panel (a second opinion from a panel of external models), claude-memory-tidy (stop your agent's memory from rotting), telegram-mcp-kit (your own Telegram over MCP in about 15 minutes).

Author: Anton Dziatkovskii, Palo Alto AI Research Lab. Telegram @tonydzi - WhatsApp +1 341 222 9178 - X @Tony_Stef_

Engineers: want to test-drive this setup? Message me. I hand out free starter seeds to engineers who test and report back, and custom skill requests are welcome.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

03

無料

Run an autonomous consensus round between agent peers on several machines: they negotiate a decision over a shared channel and execute it without a human relaying messages. Use when multiple machines must agree on a change. Triggers: "/03", "work it out among yourselves", "find consensus". Wakes the human only for irreversible actions or a deadlock.

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

1

無料

Recover a session after a hard crash (app died, machine rebooted, context lost mid-work): replay the turn-state ledger for the last requests, files and decisions, run a green/red health ping over the system map, file sync and MCP connectors, then rebuild the previous session history for pickup. Triggers: "/1", "resume after crash", "wake".

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

agenda

無料

Show the operator's day: today's calendar plus what needs them personally (leads due, people awaiting a reply, deadlines), pulled from Calendar and Telegram and ranked. Read-only: sends and commits nothing. Triggers: "/agenda", "what's on today", "my agenda".

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

ai-slop

無料

Rewrite machine-written text so it reads like a busy human wrote it: cut 50-70%, break the even rhythm, drop AI-tell words and filler, keep facts and protected terms. Use before publishing any post, reply or email drafted by a model. Triggers: /ai-slop, /slop, humanize, anti-slop, make it shorter and alive.

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

Decision protocol for strategic work: recall the knowledge vault, run a gap analysis, emit a deep-research prompt for external tools, then synthesize the returned reports into a decision memo. Use before any new product, feature, market, pricing, GTM or architecture call, where local recall alone is not enough. Triggers: "/alfa-search-recall-deepresearch", "alpha protocol", "R+DR".

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

- КРЕДИТ АВТОРУ ИДЕИ: совет из комментария (TG @ClawRus / @ClawInga, комменты под постами Антона в FB, треды и issue на… Триггеры: “/alpha-credit“, “/credit“, “кто нам это посоветовал“, “запиши совет“, “поблагодари советчиков“, “кому мы должны спасибо“, “кредит автору“, “чей это был совет“, “credit the author“

日本語の概要は準備中です。原文の説明を表示しています。

tonydzi/second-brain-starter-kit82026年10月12日 更新

tonydzi のスキルをすべて見る

このスキルの問題を報告する