跳到正文
cccskills
免费在 GitHub 公开

walk-promo

Prepare promo materials for a published otgolosok walk — a YouTube Shorts video via ../otgolosok-shorts, a Telegram post about a different story from the same walk, a Telegram illustration and a vertical YouTube cover. Use when the user passes a walk share link and asks for Shorts / Telegram post / covers.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok星标 2(GitHub 2 + cccskills 0)
集成工具TelegramYouTube

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md10.3 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Prepare a promo set for the walk $ARGUMENTS. All work happens in the sibling repo ../otgolosok-shorts (absolute: resolve from this repo's parent). Communicate with the user in Russian; all user-facing texts (post, titles, covers, journal) are in Russian.

Publishing is outward-facing. Prepare everything locally, show the result, and upload to YouTube / send to Telegram only after the user explicitly says so in this conversation.

Before starting, read in ../otgolosok-shorts: README.md (sections «Ролик по готовой прогулке», «Telegram»), docs/agents/shared-walks.md, docs/agents/cover-art.md, docs/agents/telegram.md and the most recent docs/agents/*-short-*.md journal — it is the reference for format and checks.

No abbreviations anywhere in the promo — hook, video title/description, Telegram post, cover titles: spell names out («Третье транспортное кольцо», not «ТТК»; «улица», not «ул.»), even if the story uses the short form. The generator rejects them (*_ABBREVIATION); keep the same rule in manual edits.

0. Names and folders

  • SLUG — kebab-case of start/end (e.g. spartak-tushino), DATE — today, SEED — YYYYMMDD.
  • DATA=tmp/$SLUG-video-$DATE — isolated SHORTS_DATA_DIR, so the production scheduler (auto) never picks up or publishes a manual run.
  • OUT=data/manual/$SLUG-$DATE — finished materials (ignored by git, survives cleanup).
  • Voice: argument if given, otherwise alex-bell.

1. Read the walk

curl -sS https://otgolosok.online/api/story-walks/shared/<token> → document (title, description, route.distanceM, route.walkingMinutes, mode, minutes) and chapters[] (story.title, story.paragraphs, story.sources, audio.durationSec). Save the JSON to $DATA/walk.json. Sum audio.durationSec for the total listening time.

2. Build the video

SHORTS_DATA_DIR=$DATA pnpm shorts run --template walk --walk '<url>' --voice <voice> --no-upload --seed $SEED

Run it in the background (render takes ~10 min). After the script step finishes, inspect $DATA/runs/<id>/prepared.json (stops[].photo) and script.json. If edits are needed (steps 3–4), stop the run before the render to save time — the render is redone once at the end.

3. Check the hook

Since walk-v7 the model writes the opening (script.json → hook) and validateScript checks it; if it fails, one of the fallback openings (HOOKS in src/templates/walk/script.ts) is used. Read the hook: it must name this route, not be generic, and differ from the previous videos' openings (see the last journals). If it is weak, edit it by hand: save script-before-new-hook.json, set hook.text/hook.display, check with validateScript + evidenceOf (expect an empty list), then update checkpoints (step 5).

4. Photos for all four episodes

findPhoto uses the place's tags and then the story's Wikidata/Wikipedia sources, skipping items about people. If some episodes are still without photo:

  1. Search Commons (list=search&srnamespace=6), category or file names; send a User-Agent and pause ~3 s between calls — Commons rate-limits (You are making too many requests).
  2. Check and download with the generator's own commonsCandidate + fetchPhoto (src/sources/wikimedia.ts, cache dir $DATA/cache/photos) — they enforce licence, author and size.
  3. Look at every candidate (contact sheet via ffmpeg xstack): it must show this place and match the beat's line. Reject misleading files (e.g. a boat named after the river instead of the river).
  4. Save the original as prepared-before-photos.json, set stops[i].photo = {path, sha1, width, height, attribution} from the downloaded <sha1>.json.

Single-story format (format: "story", every queue slot since 2026-10-13): at least 3 different photos of the place, never one picture for the whole story. prepare takes up to four from the place's own sources and its Commons category (stops[i].photos); the storyboard fails with STORY_PHOTOS below three. For an editorial sequence set prepared.storyPhotos (≥ 3 entries, fromSentence on the story's sentences, label/fit: "contain" for archive shots or interiors) and match each photo to its sentence; a modern facade must not pose as a specific archive shot.

5. Update checkpoints and render (only after manual edits)

In $DATA/state/shorts.sqlite (run_steps): set output_sha256 of prepare and script to the new shasum -a 256 of the edited files; delete the voice and render rows; keep mix — render --run refuses to start without mix=done, and the redone voice step invalidates it itself. Unchanged lines come from the TTS cache; only changed lines are synthesised.

SHORTS_DATA_DIR=$DATA pnpm shorts render --run <id>          # background

Always (with or without edits):

SHORTS_DATA_DIR=$DATA pnpm shorts stills --run <id> --at 1.5,8,15,23,31,39,47 --debug-safe

Check stills visually (one strip via ffmpeg hstack): hook, overview, all four photos, final card; captions must not cover photos. Check probe.json (≤ 58,5 s, 1080×1920, 30 fps), loudness.json (≈ −14 LUFS) and a full decode ffmpeg -v error -i video.mp4 -f null -. Copy video.mp4, metadata.json, script.json, probe.json, loudness.json to $OUT.

6. Telegram post — a different story

Pick a stop that is not among the four video episodes and whose story has a strong visual detail (a surprising fact, not a summary of the route). Format (see docs/agents/telegram.md and the last journal): bold headline with one emoji, a paragraph with one verified detail + source link (story.sources, Cyrillic Wikipedia URLs are shorter than percent-encoded), 🎬 line with the video link and what the video shows, 🚶 distance / walking time / total listening time, 🎧 walk link, and a note that the cover is an illustration. 3–4 emoji total. Use only facts from the story text. Caption limit is 1024 characters of HTML including tags — measure with the real video URL. Save telegram-post.draft.json with a {{VIDEO}} placeholder; write the final telegram-post.json only after the YouTube URL exists ({{VIDEO}} → <a href="https://www.youtube.com/shorts/<id>">Короткий ролик по этой прогулке</a>).

7. Covers (Codex image_gen)

Follow docs/agents/cover-art.md. If the post's object has a historical/real look, download a reference photo from Commons and pass it to the generator so it does not invent the object. Save prompts next to the images (telegram-cover-prompt.txt, youtube-cover-prompt.txt).

  • Telegram: 4:5 illustration, no text, the post's object in the foreground → telegram-cover.png.
  • YouTube: 9:16, upper 40 % — large dark-green Cyrillic title (route «ОТ … ДО …», guillemets), terracotta plaque «N ИСТОРИЙ МОСКВЫ» (N = total stops of the full walk), small «ОТГОЛОСОК»; lower 60 % — imagery of the video's episodes → youtube-cover.png.

Generate with Codex non-interactively, from $OUT:

codex exec -s workspace-write --skip-git-repo-check -C "$PWD" "<instruction: read the prompt file, call image_gen, save ./<name>.png>" -i <ref.jpg> </dev/null

Gotchas: the prompt must come before -i (it takes several files and swallows the prompt); </dev/null is required in the background, otherwise it waits on stdin forever; macOS has no timeout. Run both covers in parallel in the background. Check each image in full size and at phone width: object geometry, no stray letters on the Telegram cover, exact title spelling on the YouTube cover. Regenerate on errors. PNG ≤ 10 MB.

8. Show and wait

Report in Russian: run id, video duration/loudness, the four episodes and photo credits, the post text and its length, paths of both covers, and anything done by hand. Then wait for the user's command.

9. Publish (only on the user's explicit command; ask for the time if not given)

  • YouTube — the generator's publish command (token of the main data dir, since $DATA is isolated); the cover must be ≤ 2 MB, so convert it: ffmpeg -i youtube-cover.png -q:v 2 youtube-cover.jpg.

    YOUTUBE_TOKEN_FILE=data/secrets/youtube-token.json SHORTS_DATA_DIR=$DATA \
      pnpm shorts publish --run <id> [--publish-at 2026-10-05T19:00+03:00] --thumbnail $OUT/youtube-cover.jpg
    

    With --publish-at the video is uploaded private and YouTube makes it public itself; the URL is known at once. Confirm via videos.list (privacyStatus, publishAt). thumbnails.set does not change the Shorts-feed thumbnail — tell the user to pick it in YouTube Studio.

  • Telegram: finalize telegram-post.json with the video URL, copy it with the cover into the run dir. Now: SHORTS_DATA_DIR=$DATA pnpm shorts telegram:send --run <id> (idempotent via telegram-delivery.json). At a time: the Bot API cannot schedule — reuse the one-off server cron job described in the latest shorts journal (copy the previous job directory with the new post, cover and schedule.json, run its --check in the container, add the cron line in UTC). This is a production change: do it only because the user asked for a scheduled post, and never write server addresses into this public repo.

Helper scripts (Commons check, validateScript run) are throwaway: pnpm check lints every .ts under the repo including tmp/, so delete them (or keep them outside the repo with absolute imports) before running checks.

10. Journal and commit

Write docs/agents/$SLUG-short-$DATE.md in ../otgolosok-shorts (Russian, same structure as the previous journal: прогон, сценарий, фотографии, Telegram, обложки, проверки, публикация) and add it to docs/agents/README.md. Run pnpm check, then commit there: docs(video): <описание по-русски>. No secrets, tokens, server addresses or data/ files in git.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Качество русского текста для агента. Russian text quality for agents: proofreading and AI-slop cleanup for Cyrillic text. Триггеры: очеловечь, вычитай, отредактируй, поправь, причеши, проверь текст, убери канцелярит, humanizer. Молча снимает жёсткие запреты в собственном русском выводе агента; чужой текст молча не трогает. Use when надо убрать из русского текста канцелярит, воду и нейросетевую манеру, не сломав смысл, факты и голос автора. Три режима по запросу: редактура, аудит без переписывания, точечная правка одной категории. Со скиллом едет детерминированный сканер scripts/scan.py: считает хард-баны, категории маркеров, ритм и морфологию, печатает ЧИСТОТА: N/100, поэтому правка измерима («было N, стало M»). Флаг --genre academic/legal/fiction/news снимает маркеры, законные для научного, юридического и новостного регистра. Работает ТОЛЬКО с русским: для английского humanizer, для итальянского humanizer-it. НЕ используй для: перевод, написание с нуля, грамматика без стилистики, код.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

Implement an existing plan from docs/agents/plans/. Use when the user asks to implement, execute, resume, or continue a plan, or references a plan file — the plan's Status line must be updated on completion.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

make-plan

免费

Create an implementation plan for any task — feature, refactor, migration, fix — and save it to docs/agents/plans/. Use when the user asks to plan work, write an implementation plan, or prepare a task spec for claude/codex. (Implementing an existing plan is the implement-plan skill, not this one.)

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

Review a project for production readiness. Invoked manually by the user via /production-readiness before deploying or preparing a release.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

Подбирать варианты новых промопрогулок из уже озвученных точек production — минимум 10 точек, от 17 минут аудио, не больше 50 % точек из любой существующей промопрогулки. Применять при просьбах найти, проанализировать или предложить новые промопрогулки или проверить пересечение идеи прогулки с опубликованными.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

Переписывать русские рассказы о городских точках, перегруженные датами, — цепочки «в 1884 году… 9 февраля 1885-го… в 1989-м… в декабре 1993-го» скучно слушать. Оставлять одну-две опорные даты, остальные выражать через промежутки («через десять лет», «спустя два столетия», «в конце 1980-х»), не теряя смысла и точности. Применять при просьбах убрать перебор дат, сделать рассказ живее на слух или проверить точки, прогулку, партию рассказов на перечисления годов.

中文简介正在准备中。当前显示原文说明。

softmg/otgolosok22026年10月29日 更新

查看 softmg 的全部技能

报告此技能的问题