# Any2video

> Deep-analyze any input (URL, GitHub repo, article, image, raw text) and produce a chi-tiết video with non-templated visuals + voice narration. Unlike a fixed-template video generator (fixed layouts + themes + a small fixed context), the agent does the deep extraction, writes the plan, then composes each scene as bespoke animated visuals (Remotion by default, with an HTML-template path as fallback…

- **Type:** Skill
- **Install:** `agentstack add skill-chanktb-any2video-skill`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [chanktb](https://agentstack.voostack.com/s/chanktb)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [chanktb](https://github.com/chanktb)
- **Source:** https://github.com/chanktb/any2video/tree/master/skill

## Install

```sh
agentstack add skill-chanktb-any2video-skill
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# any2video — Deep Video from Any Input

Claude is the planner + visual designer. Result: each video looks designed for its content, not slotted into a pool of fixed layouts.

## When to use this skill vs a quick templated generator

| Situation | Tool |
|---|---|
| Quick FB/IG video from an article URL, default branding | a fixed-template generator |
| Repo URL, code-heavy explanation needed | **any2video** |
| Raw text → video, needs custom visual treatment | **any2video** |
| Bulk video gen, API-shape, scale to many users | a fixed-template generator |

Runs on any coding agent — Claude Code, **Antigravity**, etc. Phase 4 injects data
into templates instead of hand-writing HTML per scene, so a run is a normal agent
session, not a token-heavy job. Best for videos you want to look bespoke; a
fixed-template generator is still the better fit for high-volume, uniform output.

## Render path (DEFAULT: Remotion free-compose, v8)

**Default render = path B (Remotion).** Free-composed React scenes read as more
bespoke than the CSS-template path, so unless the run opts out (below), keep Phase
0-2 (intake, deep extract, narrative plan) unchanged and run Phase 3-5 with the
process in [references/remotion-render.md](references/remotion-render.md). The
engine lives in `render-remotion/` (`npm i` on first use): scenes are composed
freely from primitives following the content's structure (NO template pool,
doctrine in `render-remotion/SCENE-DESIGN.md`), 14 skin tokens in `src/lib/skins.ts`
(visual gallery in `render-remotion/docs/skins/`; repo tours default to the
`repo-dark` hybrid skin), voice + word timestamps via `tools/gen_voice.py`
(edge-tts), `tools/gen_voice_google.py` (Chirp3 HD), or `tools/gen_voice_vieneu.py`
(VieNeu-TTS local: free, instant voice cloning, bilingual code-switching with
English terms written raw), gates via `tsc` + a still-check of every scene.
Complete living examples: `render-remotion/src/videos/flow-movie-pipeline-pop.tsx`
and `flow-movie-pipeline-tour.tsx`.

**Opt out to path A (HTML templates + Playwright)** when the user says "--html" /
"--playwright" / "--fast", OR when Node/Remotion is unavailable in the environment
(no `render-remotion/node_modules`, or `npm`/`npx` missing): then fall back to
path A automatically. Path A is the fast, turnkey path where Phase 4 fills the
template catalog via `template_render` (the 6-phase workflow below documents it
end-to-end, and it shares Phases 0-2 + all quality gates with the Remotion path).

## Workflow — 6 phases, 7 quality gates (Phase 0 + 3.5 + 6 added 2026-06-30)

### Phase 0 — Interactive intake (NEW)

Before any clone / WebFetch, ask the user 4 questions in ONE message (AskUserQuestion or plain prompt):

1. **Input** — URL repo / URL article / paste raw text? (skill detects type from string)
2. **Output folder** — default `workspace/runs//` hay custom path?
3. **Media riêng?** — user có ảnh/clip muốn chèn (screenshot, b-roll, clip output…)? Nếu có → bảo họ bỏ file vào `runs//assets/`; Phase 2 đặt vào đúng beat qua `frame-media-full`. Xem CATALOG.
4. **Gửi Telegram** — gửi 2 checkpoint duyệt (kịch bản trước TTS + hình scene trước render) và final.mp4 về DM? `[Y/n]` (default Y)
5. **Caption** — (chỉ nếu Y ở câu 4) caption cho post final hay `auto` để skill tự gen từ tiêu đề source

**User media (ảnh/clip):** một template duy nhất `frame-media-full` cho CẢ ảnh lẫn video — **full-width, không khung, không safezone**, `object-fit: contain` (thấy trọn nội dung, ko crop; clip 9:16 lấp đầy, ảnh dọc full width + dải tối trên/dưới có chấm theme). Video tự phát; ảnh đứng yên. Slot `media` nhận URL `https://` hoặc `file:///…assets/x`; tự nhận ảnh vs video theo đuôi. Chèn vào **body** (sau scroll / cạnh claim để làm proof), KHÔNG để media sáng-trắng làm scene 1 (ship-gate chặn thumb trắng). Scrim + karaoke + nền + ship-gate dùng chung, không cần chỉnh.

**Steering overview (repo + text, optional):** khi input là repo mà mình lo AI phân tích lệch trọng tâm (nhấn sai vấn đề / bỏ sót "vũ khí" repo muốn khoe), user đưa THÊM một đoạn text mô tả đúng hướng repo muốn thể hiện. Repo VẪN được clone + đọc code như thường; overview chỉ là tham chiếu ĐỊNH HƯỚNG. Truyền qua `init --overview-file ` (ưu tiên file để không hỏng dấu tiếng Việt) hoặc `--overview ""`. Lưu ở `runs//overview.md`; Phase 1/2 coi nó là nguồn framing ưu tiên khi tín hiệu của repo (README/marketing) và overview lệch nhau về trọng tâm. Áp dụng được cho cả article/text, không riêng repo.

If args present on `/any2video ` invocation, skip Q1. Otherwise wait for answer.

Save intake to `workspace/runs//intake.json`:
```json
{
  "input": "https://github.com//",
  "output_dir": "workspace/runs/-/",
  "telegram": true,
  "caption_mode": "auto" | ""
}
```

### Phase 1 — Source routing + deep extract

Detect input type:
- **GitHub repo URL** → `git clone --depth 1` to `workspace/scratch//repo/`, then
  READ THE CODE (see §1.1 — HARD, not optional):
  - `README.md` + manifest (`package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml`) for stack + the author's *declared* intent
  - Build the tree (depth ≤ 3, skip `node_modules` / `.git` / `dist`), pick the entry point(s) + **3–7 core files and OPEN them**
  - **Trace the real end-to-end flow through the code** (entry → key functions → output) — not the README's diagram
  - `git log -n 15 --oneline` + skim the newest-touched files for what's actually active
- **Article URL** → WebFetch, strip nav/footer, keep body + outline
- **Image** → vision: describe scene, extract text (OCR via Claude vision)
- **Raw text** → passthrough

#### 1.1 Read the code, not just the README (HARD)

The README is the author's *pitch* — what they WANT you to think. It is NOT a reliable
source of what the repo actually does, how it works, what's clever, or what's broken.
**A repo tour built only from the README is disqualified — re-open Phase 1 and read the
source.** Before writing `analysis.md` you MUST open and read the actual code:

1. **Trace the real flow** from the entry point through the core files to the output.
   Describe the pipeline you SAW in code, not the one the README claims.
2. **Find the good — the non-obvious "weapon".** The 2–3 clever mechanisms worth a video
   live in the code, not the marketing bullets: a specific algorithm, a guard, a data
   structure, a regex, a scheduling trick, a fallback. Name the file it's in.
3. **Find the bad — the honest caveat.** Read for the real limits: `TODO` / `FIXME`,
   `NotImplementedError`, hardcoded assumptions, narrow scope, missing error handling,
   "only works if…". This feeds the mandatory honest-caveat scene (§2.2.7 item 3).
4. **Cross-check every README claim against the code.** If the README says "supports X"
   and no code does X, DROP the claim — never repeat an unverified README boast (see the
   §2.2 auto-fail "describe the README instead of the product").

Every `## Evidence` line backing an Architecture / Flow / weapon / caveat claim MUST cite
a real `path/to/file.ext:symbol` (or line) — NOT a README sentence. "Implied by README" = fail.

**Steering overview (HARD — when `source_pack.json` has `has_overview: true`).** The operator
supplied `runs//overview.md` — their authoritative statement of what this source is
*really* about and the problem→solution angle it wants to lead with. Read it FIRST. Still read
the code / article for evidence + specifics, but let the overview set the ANGLE: which Problem,
which hero "weapon", which hook. Where the source's own signals (README/marketing) and the
overview disagree on emphasis, PREFER the overview. Cite it in `## Evidence` as `overview.md`,
and any scene it drives gets `grounded_in: overview.md`. This exists to fix "the AI missed the
point" — it steers, it does not replace the code-reading above.

Write **`workspace/runs//analysis.md`** with this fixed structure:

```markdown
# Analysis: 
## Problem
What problem does this solve? Who has it? Why does it matter?
## Solution
What's the approach? What's novel?
## Architecture
Key components, how they fit together.
## Flow
End-to-end workflow: trigger → steps → output.
## How to use
Concrete usage: install, invoke, configure.
## Why it matters
Audience, impact, what differentiates it.
## Evidence
Real numbers, quotes, file references — proof for every claim above.
```

**Gate 1 (Sonnet critic):** every claim in Problem/Solution/Architecture/Flow has ≥1 citation in Evidence — AND, for a GitHub repo, the **Architecture + Flow + at least one "weapon" + the caveat cite an actual SOURCE FILE** (`path:symbol`/line), not the README. If every Evidence line is a README quote, the agent skipped the code → **fail the whole analysis, re-read the source, regenerate.** No citation / README-only citation on a code claim → flag, regenerate that section.

### Phase 2 — Narrative plan (the critical phase — read carefully)

**This is where most any2video runs FAIL the quality bar.** The output is a script the viewer hears — not a marketing card. Treat it as scriptwriting for a friend showing you something on their laptop, not a product slide deck.

#### 2.1 Narrative principles (HARD — these are what separate "cuốn hút" from "tệ")

Derived from the Palmier Pro reference + common templated-video anti-patterns. The 9 patterns:

1. **Pain-first / mid-conversation opening.** Open on the viewer's pain or a stat already-in-flight ("Nếu bạn hay phải …", "Repo này có 9 nghìn sao …"). NEVER a flat catalogue opener: "Đây là một công cụ …", "Hôm nay xem qua repo này …", "Hôm nay chúng ta sẽ tìm hiểu …". A "Hôm nay xem qua X, một công cụ …" opener has no hook, names no problem, and gives the viewer zero reason not to scroll — see §2.2.5.0 Intro pain-hook.
2. **Contrast structures.** Use "không chỉ X mà còn Y", "cứ như X nhưng có Y", "không phải X mà là Y", "Nhưng lưu ý …". Contrast pulls attention.
3. **2nd-person address.** "bạn thấy ngay", "Bạn có thể trim, replace", "Nếu bạn dựng video trên Mac dòng M". Brings the viewer in.
4. **Demonstrative immediacy.** "ngay", "này", "trên đây", "ngay trên timeline", "ngay trong cùng editor này". Concrete and present.
5. **Specific real names + keep the jargon.** Name actual files, commands, competitors, brands — "Final Cut", "Cursor", "Claude Code", "FLUX", "Edge TTS", "ffmpeg". Generic terms ("AI tool", "the framework") are forbidden. And keep the STANDARD technical term — don't force-translate jargon into awkward Vietnamese ("phrase match" NOT "khớp câu", "keyword" NOT "từ chìa khoá"). Write it in a natural, spoken register (see §2.2.6 f).
6. **Quantified social proof** — but ONCE, not as a sidebar dump. Frame with hedge: "hơn 9 nghìn sao", "khoảng 600 fork". Never list stars + forks + issues + license back-to-back.
7. **Short clauses, comma-flowed.** "Bạn có thể trim, replace, hay regenerate phần đó." One breath. Not bullet fragments.
8. **Caveat-as-feature.** "Nhưng lưu ý, editor và MCP server miễn phí, còn AI generation cần mua thêm credit." Honest framing > marketing fluff.
9. **Use-case landing.** Close on a SPECIFIC viewer scenario: "Nếu bạn dựng video trên Mac dòng M …" / "Nếu repo bạn đang xây có 3-5 file lõi …". Not "Hãy ghé repo xem thử nhé."

#### 2.2 What the narration MUST NOT do (auto-fail patterns)

- ❌ Treat scenes as Hook/Problem/Solution/CTA fill-in-the-blank
- ❌ List GitHub sidebar stats as separate fragments ("Một dòng lệnh. Một video. Không tốn xu nào.")
- ❌ Restart each sentence as a stand-alone bullet ("Repo X runs one pipeline. Gemini writes. Edge TTS narrates.")
- ❌ Generic capability claims ("đầy đủ tính năng", "rất mạnh mẽ", "phổ biến trong cộng đồng")
- ❌ Describe the README/repo instead of the product ("README rất chi tiết và đầy đủ")
- ❌ Close with "Hãy ghé repo và xem thử nhé"

A good example to internalize:
> "Hermes định vị là Agent tự hành — không phải chatbot — với trí nhớ dài hạn lưu state qua nhiều phiên."

That single sentence has: contrast (`không phải … mà là`), specific name (`Hermes`), specific design choice (`trí nhớ dài hạn lưu state qua nhiều phiên`). One sentence does the work of 3 generic ones.

#### 2.2.5 The narrative arc (HARD — the opening decides retention)

A GitHub tour runs this arc **in this order**. The first seconds decide whether the viewer stays, so the opening is FIXED (PA1, feedback 2026-07-02): **open on the biggest pain, NOT a title card.** A repo slug means nothing to a stranger; a pain they feel does.

| # | Beat | Sec | What it does |
|---|------|-----|--------------|
| 1 | **pain hero (biggest)** | 5-7 | `frame-pain-hero`: open on the viewer's BIGGEST pain — full-bleed, top-anchored, beautiful. Carries a **subtle github context chip** (owner avatar + GitHub mark + `owner/repo`, author's casing) so viewers sense it's a real tool without a title card. This IS the hook. |
| 2..k | **pain blocks** | 4-6 each | more `frame-pain-hero` scenes, ONE felt pain each, **highlighted as it's spoken**. Rows 1..k = **4-6 pains total**, 2nd-person, each named concretely, so the opening is dynamic. |
| k+1 | **reveal / overview** | 3-5 | `frame-repo-identity`: the pivot "…thì repo này giúp bạn" — cut to avatar + `owner/repo` + tagline. **Conditional social proof:** popular repo → a stars/forks/language row; new repo → a quiet "mới ra mắt" tag (omit stars). Sits DIRECTLY before the scroll. |
| pivot | **repo scroll** | = its narration | full-bleed repo-scroll (`capture_url: https://github.com//`). Describe what the repo solves; tune its `duration_sec` so the description finishes exactly as the scroll ends. |
| k+3 | **problem** | 5-8 | NOW go into detail on the specific problem the repo tackles. |
| k+4 | **details** | 7-10 | One differentiator — the thing nobody else does. |
| k+5 | **review** | 5-8 | Honest caveat-as-feature. "What to know before installing." |
| k+6 | **author outro** | 6 | Author-profile scroll (`capture_url: https://github.com/`) — ends with a **star nudge** (§2.2.5.0). |
| k+7 | **promo** | 4 | `frame-made-with` "made with any2video" bumper — the FINAL scene, default ON (§2.2.7 item 10). |

Total target: 50-80 sec. `plan_critic` enforces: scene 1 = `frame-pain-hero`; ≥4 pain scenes (all `frame-pain-hero`, so each carries the chip); the reveal card `frame-repo-identity` sits DIRECTLY before the repo-scroll; a repo-scroll scene exists; the closing content scene is author-profile footage with a star line; promo (if present) is last.

##### 2.2.5.0 Opening pains + closing star (HARD — the opening seconds decide the scroll)

There is **NO title-card intro**. Open on the viewer's BIGGEST pain (`frame-pain-hero`) — full-bleed, top-anchored, beautiful, with a subtle github chip. The remaining pains follow as more `frame-pain-hero` blocks (**4-6 pains total**), each naming ONE felt pain, highlighted as it's spoken. The repo's identity is a **REVEAL, not an intro**: only after the pains land on the pivot does it appear. The OLD flat opener ("Hôm nay xem qua repo này…" / "Đây là một công cụ…") stays banned.

**Pain-blocks pattern (HARD):** lead the FIRST block with the target viewer's biggest pain-task, then let each following block add one more felt frustration, all 2nd-person:

```
[block 1 = hero] "Bạn hay phải [BIGGEST pain-task the audience does] đúng không."
[block 2] "Rồi lại [second friction they hate]."
[block 3] "Mà [third friction]…"
[block 4] "Và [fourth friction]."
→ pivot: reveal card (frame-repo-identity) "…thì repo này giúp bạn [one-breath value prop]"
→ CUT to repo scroll
```

- Each pain block is atomic (one idea), 2nd-person, and **highlights the key phrase as spoken** (the karaoke caption + a visual accent land together).
- **Conditional reveal (HARD):** the reveal card is always present at the pivot, but its overview is conditional — popular repo (many stars/forks) shows a stars/forks/language row; a new/low-star repo skips stats and shows a quiet "mới ra mắt" tag, then cuts straight to the scroll.
- **Where the pains come from:** `analysis.md > ## Problem` ("Who has it? Why does it matter?"). Same audience, s

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [chanktb](https://github.com/chanktb)
- **Source:** [chanktb/any2video](https://github.com/chanktb/any2video)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-chanktb-any2video-skill
- Seller: https://agentstack.voostack.com/s/chanktb
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
