# sk-brief

Adopt this skill: https://proskills.md/skills/other/howznguyen-shorts-kit-claude-skills-sk-brief

Page: https://proskills.md/skills/other/howznguyen-shorts-kit-claude-skills-sk-brief
This document is the public skill bundle for that page. It contains SKILL.md and every helper file the catalog carries. No login is required.

## File: .claude/skills/sk-brief/SKILL.md
size: 3019
sha: 44a30472d2ffe5585c95d1a4c09a6059e9a65c53
upstream: https://github.com/howznguyen/shorts-kit/blob/main/.claude/skills/sk-brief/SKILL.md

````text
---
name: sk-brief
description: Starts a new short by stating the idea in one sentence, picking the storytelling flow and the visual types, checking image licences before any script exists, scaffolding the video folder, and writing briefs/<id>.md. Use when the user says "new video about X", "write a brief", "which flow fits this topic", "how should this look on screen", "scaffold a video", or "can I use this image". Steps 1, 3 and 4 of sk-pipeline.
---

# sk-brief: idea, flow, visuals, brief

**Announce:** "Using sk-brief for <id>."

Rules: `SOUL.md` three first rules, §1, §2 (`docs/soul/01-voice-and-structure.md`),
§5 (`docs/soul/03-visuals.md`), §13 (`docs/soul/10-files.md`). The § wins over
this file.

## Order (do not swap)

1. **One sentence: what can the viewer repeat after watching?** If you cannot
   write it, the topic is not ready. This sentence is the brief's first line.
2. **Facts first.** Every claim you plan to use needs a `verified` record in
   `docs/facts/facts.json`. Missing ones: run `sk-facts` now, before writing.
3. **Pick the flow.** Read `docs/flows/README.md`, then the candidate flow files,
   especially "When to use" and "Traps". Do not default to the first flow out of
   habit: ask what shape the fact has (a list of reasons, a trace back to a cause,
   a single person, a comparison). Sketch at least two shapes, pick one, and note
   in the brief why the other lost.
4. **Pick the visual types** from `docs/visuals/README.md` (e.g. `text-as-image`,
   `timeline`, `archive-plate`, `news-photo`, `gif`, `b-roll`) and read each
   chosen type's file. Flow is how the story is told; visual is how it gets on
   screen. They are independent axes.
5. **Check the licence of every image and clip now.** Record each in
   `docs/facts/sources.json` with its `licence`. An image you cannot license is a
   claim you cannot show; find another visual or cut the claim before scripting.
6. **Scaffold:**
   ```bash
   bun run new <id> --flow <A..N>
   ```
   Then set `visual` in `src/videos/<id>/narration.json` to the chosen ids.
   `id` follows §13 (lowercase, hyphenated, never reused for a different video).
7. **Write `briefs/<id>.md`** from `briefs/_template.md`.

## What the brief holds

- The one-sentence idea and the angle (what the viewer believes now, and the
  turn that negates it).
- Flow chosen, why, and the shape that was rejected.
- Visual types and, per scene, what is on screen.
- A fact table that points at **ids** (`f-0001`), not copied numbers or URLs. A
  copied number goes stale silently when the ledger is corrected.
- Image list with source ids and licences.
- An empty "Posted" section, filled in after upload (`sk-improve`).

## Verify

- [ ] `flow` in `narration.json` matches the flow named in the brief
- [ ] `visual` is set and every id exists in `docs/visuals/`
- [ ] every fact id in the brief exists in `docs/facts/facts.json`
- [ ] every image has a source record with a licence
- [ ] `bun run facts` exits clean

Next: `sk-narration`.
````

## File: README.md
upstream: https://github.com/howznguyen/shorts-kit/blob/main/README.md

````text
<p align="center">
  <img src="docs/assets/logo.png" alt="shorts-kit logo" width="128">
</p>

# shorts-kit

[![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.knowns.dev)
[![Facebook group](https://img.shields.io/badge/Facebook-Agentic%20Coding%20Vietnam-1877F2?logo=facebook&logoColor=white)](https://www.facebook.com/groups/agentic.coding.vietnam)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)

![shorts-kit: narrated vertical shorts, made with your coding agent](docs/assets/cover.jpg)

Make narrated vertical shorts (TikTok, YouTube Shorts, Reels) with a coding agent and
[Remotion](https://www.remotion.dev).

You talk to your agent ("make a video about why the sky is blue"). The agent follows
the kit's skills step by step: facts first, a storytelling flow, the script, the voice,
the scenes, stills to check, the render, the cover and the caption. You review, then you
upload the file yourself. The kit never posts anything.

The rules and skills come from a private pipeline that took a new knowledge channel from
zero to about 120k views on its best video in two months. Every rule keeps the reason it
exists, because most of them were written after a published video broke it. They are
defaults: change them for your own channel.

## Results

The channel these rules came from, two months in. The best videos and the flops sit side
by side on purpose: topics close to the audience carried it (tens of thousands of views),
topics that drifted from the channel's niche got a few hundred. The kit cannot pick your
topic for you.

![A TikTok profile grid: 122.1K, 63.3K, 48.4K, 31.7K and 11.8K views next to 3,692, 768, 349 and 232](docs/assets/tiktok-results.jpg)

What a finished run reports, from the original private pipeline (it also copied files to
a NAS and applied that channel's own swearing rule; neither is part of this kit):

![An agent's end-of-run report: narration, TTS, scenes, render, loudness and encode, cover, caption, hand-off, and the fact checks it caught](docs/assets/agent-run.jpg)

## What is in the box

- **9 agent skills** (`.claude/skills/sk-*`), started by `sk-pipeline`. They work in
  Claude Code, and in any agent that reads `AGENTS.md` (Codex, OpenCode, ...).
- **SOUL.md**: your channel's rulebook. Voice, sentence style, writing for a
  text-to-speech voice, safe zones, captions, audio, facts, covers, hand-off. Each rule
  is tagged `[measured]`, `[default]`, `[craft]` or `[hard]` so you know how freely to
  change it.
- **20 storytelling flows** (`docs/flows/`): Three reasons, Trace back, Explain it,
  Reading a graph, Empty world with a late reveal, and more. Each has beats, when to use
  it and its traps.
- **A fact ledger** (`docs/facts/`). No sentence goes into a script before its claim
  has a verified record, and the linter enforces it.
- **A Remotion library** (`src/shared/`): word-timed captions, kinetic type, safe-zone
  overlay, music bed and SFX, camera moves, and an illustrated world (sky, sea, sun,
  moon, stars, clouds, rain, birds, people, fish).
- **Maps and a globe** (`src/shared/map/`): satellite imagery with a camera that flies
  from country to street and stays sharp, coastlines, borders and rivers from Natural
  Earth, routes that draw on, pins, measured distances, filled regions, a ready Vietnam map
  with the Hoàng Sa and Trường Sa archipelagos, a 3D globe with great-circle lines, and a
  pull-out from any scene to the globe.
- **Shared graphics** for any video: strike-and-replace, slot word, word slam, typewriter,
  hand-drawn circles, arrows, underlines, cross-outs and stamps, and charts that stay true to
  scale (compare bars, progress ring, unit grid, odometer). Browse them with `bun run dev gallery`.
- **Your own voice or footage instead of TTS** (`bun run ingest`, `bun run cut`): Whisper
  transcribes the recording, fillers, retakes and long silences are proposed as cuts, and
  the cut voice drives the video like a TTS voice would. Film yourself (`talking-head`, the
  take is the background and effects stay off your face) or bring a voice recording only.
  The words stay what was said: every claim in them still needs a verified fact. See
  [docs/visuals/talking-head.md](docs/visuals/talking-head.md).
- **8 CC0 sound effects** generated by the kit (`public/sfx/`), and a guide to using
  them ([docs/sfx.md](docs/sfx.md)).
- **Scripts** for every step, from TTS with word timestamps to a platform-ready encode.
- **A local dashboard** (`bun run preview`) showing each video's progress, the render,
  the stills, the cover at profile-grid size, and the caption ready to copy. The Script tab
  plays the voice with the spoken word highlighted; the Storyboard tab shows every planned
  shot with its line, still and playback, for approval before scenes are built. The steps
  it tracks come from `docs/pipeline.json`, so a step your channel adds shows up too.

![The preview dashboard: the example video at 12/12 steps, with its player, voice timings and stills](docs/assets/preview.jpg)

## Requirements

- [Bun](https://bun.sh) 1.3 or later
- [ffmpeg](https://ffmpeg.org) and ffprobe on your `PATH`
- A coding agent: [Claude Code](https://claude.com/claude-code), Codex, OpenCode, ...
- A voice. The default depends on the video's language; pick another any time:
  - **English → `edge`** (Microsoft Edge online voices): free, no key. The service
    sometimes stops answering; `bun run tts` retries.
  - **Vietnamese → `vieneu`** ([VieNeu-TTS](https://github.com/pnnbao97/VieNeu-TTS)):
    free and offline on CPU, 25 preset voices or clone your own. Needs Python 3.10+.
  - [ElevenLabs](https://elevenlabs.io): best quality in either language, needs an API key.
  - `say` (built into macOS): free and offline, for testing only. The example uses it
    so the kit runs with no network.
  - **Your own recording** (optional): needs [whisper.cpp](https://github.com/ggml-org/whisper.cpp)
    (`whisper-cli`) and its `large-v3-turbo` model, below.

Install the tools:

```bash
# macOS
brew install bun ffmpeg

# Linux
curl -fsSL https://bun.sh/install | bash
sudo apt install ffmpeg

# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
winget install ffmpeg
```

## Install

```bash
git clone https://github.com/howznguyen/shorts-kit.git
cd shorts-kit
bun install
```

For ElevenLabs, copy `.env.example` to `.env` and set `ELEVENLABS_API_KEY`.

For VieNeu (Vietnamese), install it once into a local Python env (needs [uv](https://docs.astral.sh/uv/)):

```bash
uv venv --python 3.12 .venv-vieneu
uv pip install --python .venv-vieneu/bin/python vieneu
.venv-vieneu/bin/python scripts/lib/engines/vieneu_bridge.py --voices   # downloads the model (~600 MB), lists voices
```

Then in `narration.json`: `"voice": {"engine": "vieneu", "voice": "Thiện Minh"}`. `voice`
is a preset name or the path to a 3–8 s `.wav` to clone (only a voice you have the
right to use).

To use your own recording instead of TTS, install whisper.cpp and download the model once (1.6 GB):

```bash
brew install whisper-cpp     # macOS; on Linux or Windows build it from github.com/ggml-org/whisper.cpp
mkdir -p .cache/whisper && curl -L -o .cache/whisper/ggml-large-v3-turbo.bin \
  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin
```

## Check that it works

Build the example video ("Why is the sky blue?", about 43 s) from start to finish. On
macOS this needs no key and no network except for fonts:

```bash
bun run tts example        # voice + word timestamps
bun run lint example       # machine checks: 0 errors expected
bun run render example     # out/example/example.mp4
bun run cover example      # out/example/example-cover.png
bun run normalize example  # loudness to -13 LUFS
bun run encode example     # out/example/example-upload.mp4, ready to upload
bun run preview            # open http://127.0.0.1:7788
```

On Linux or Windows there is no `say`: set `"engine":
````
