Install
$ agentstack add skill-joeseesun-qiaomu-cut-skill-video-gen ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
When to Use
- User wants to generate an AI video from a text description
- User wants to animate a still image (first-frame)
- User has reference images to guide video generation
- User wants to edit an existing video (change style, background, etc.)
- User wants to lip-sync a video to audio or TTS (PixVerse only) — "对口型", "口型同步"
- User wants a marketing ad / promo mix video (PixVerse agent)
- User says "生成视频", "做视频", "video generation", "text to video", "视频编辑", "pixverse", "口型"
When NOT to Use
- User wants an explainer video with narration and AI visuals (use
/explainer) - User wants to transcribe audio/video to text (use
/asr) - User wants to generate an image (use
/image-gen)
Purpose
Generate AI videos using the ListenHub CLI. Supports three model families:
- HappyHorse (default) — text-to-video, image-to-video, reference-image-to-video, video-edit
- SeeDance — text-to-video, frame mode (first + last frame), reference mode (images, videos, audio)
- PixVerse — nine atomic capabilities via the Agent API (texttovideo, imagetovideo, transition, multitransition, fusion, restyle, mimic, lipsync, agent). The only family that supports lip sync. OpenAPI-only, URL/ID based, and uses its own
pixverseCLI namespace.
Hard Constraints
- Always check CLI auth following
shared/cli-authentication.md - Follow
shared/cli-patterns.mdfor CLI execution, errors, and interaction patterns - Always read config following
shared/config-pattern.mdbefore any interaction - Follow
shared/output-mode.mdfor result presentation —downloadmode saves{slug}.mp4to cwd with dedupe pershared/config-pattern.md§ Artifact Naming - Always use
--no-wait --jsonfor video creation — generation takes minutes - Never use
evalto execute CLI commands — always invokelistenhub video ...directly with proper quoting
Use the AskUserQuestion tool for every multiple-choice step — do NOT print options as plain text. Ask one question at a time. Wait for the user's answer before proceeding to the next step. After all parameters are collected, summarize the choices and ask the user to confirm. Do NOT call the video generation command until the user has explicitly confirmed.
Model Comparison
| Feature | HappyHorse (default) | SeeDance | PixVerse | |---------|---------------------|----------|----------| | Text-to-video | ✅ | ✅ | ✅ (text_to_video) | | Image-to-video (first-frame) | ✅ | ✅ (+ last-frame) | ✅ (image_to_video) | | Reference images | ✅ (1–9, with [Image N] prompt syntax) | ✅ | ✅ (fusion, @refName syntax) | | Transition (first→last) | ❌ | ✅ (frame mode) | ✅ (transition / multi_transition) | | Video edit | ✅ | ❌ | ❌ | | Restyle | ❌ | ❌ | ✅ (restyle) | | Mimic (motion transfer) | ❌ | ❌ | ✅ (mimic, locked 720p) | | Lip sync | ❌ | ❌ | ✅ (lip_sync, audio or TTS) | | Marketing agent (ad/promo) | ❌ | ❌ | ✅ (agent: admaster / promomix) | | Reference video | ❌ (use video-edit instead) | ✅ | ✅ (mimic / lipsync source) | | Reference audio | ❌ | ✅ | ✅ (lipsync) | | Resolution / quality | 720p, 1080p | 480p, 720p, 1080p | 360p, 540p, 720p, 1080p | | Duration range | 3–15s | 4–15s | 1–60s (agent: 20/30/60) | | Aspect ratios | 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4 | 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 | 9:16, 16:9, 1:1, 4:3, 3:4 | | Prompt length | ≤2500 中文 / ≤5000 非中文 | ≤500 | ≤2048 | | Rate limit | 5 RPM | 5 RPM | 5 RPM | | CLI namespace | … video create | … video create | … video pixverse generate (OpenAPI only) |
Lip sync is PixVerse-only — HappyHorse and SeeDance do not support it. Mimic, restyle, fusion, transition, and the marketing agent are also PixVerse-exclusive.
Step -1: CLI Auth Check + Video Command Gate
Follow shared/cli-authentication.md § Auth Check. If CLI is not installed or not logged in, auto-install and auto-login — never ask the user to run commands manually.
After standard auth check, verify the video subcommand is available:
if ! listenhub video --help &>/dev/null; then
npm install -g @marswave/listenhub-cli@latest
if ! listenhub video --help &>/dev/null; then
echo "VIDEO_COMMAND_UNAVAILABLE"
fi
fi
If VIDEO_COMMAND_UNAVAILABLE: stop and tell the user:
> video-gen 需要 listenhub-cli 的最新版本,当前已安装版本不包含 video 命令,请等待新版发布。
Auth Mode Detection
The CLI supports two auth modes. Detect which one is active:
# Check if OpenAPI key is configured
OPENAPI_STATUS=$(listenhub openapi config show --json 2>/dev/null)
HAS_OPENAPI=$(echo "$OPENAPI_STATUS" | jq -r '.source // empty')
# Check if internal auth is active
AUTH=$(listenhub auth status --json 2>/dev/null)
HAS_INTERNAL=$(echo "$AUTH" | jq -r '.authenticated // false')
Priority: If both are configured, prefer internal auth (richer features). Set a session variable:
if [ "$HAS_INTERNAL" = "true" ]; then
CMD_PREFIX="listenhub video"
elif [ -n "$HAS_OPENAPI" ]; then
CMD_PREFIX="listenhub openapi video"
else
# Neither configured — trigger internal auth login
listenhub auth login
CMD_PREFIX="listenhub video"
fi
All subsequent commands use $CMD_PREFIX instead of hardcoded listenhub video. The flags and JSON output format are identical between the two modes.
OpenAPI-specific notes:
- OpenAPI mode requires API Key (
lh_sk_...), configured vialistenhub openapi config set-keyor envLISTENHUB_API_KEY - OpenAPI mode does not support
--audio-settingflag (video-edit audio control not yet exposed) - Standard
listenhub openapi video createaccepts local image/video/audio paths or URLs. Local files are uploaded by the CLI before task creation; local images also get width/height/size metadata automatically. - Remote Seedance image URLs still need explicit
--*-metavalues because the CLI does not download remote assets to infer dimensions. - PixVerse is OpenAPI-only — it lives under
listenhub openapi video pixverseand has no internal-auth equivalent. If the user wants PixVerse (口型/mimic/restyle/fusion/transition/agent) but only internal auth is configured, prompt them to configure an OpenAPI key first. - PixVerse media inputs remain URL/ID based. Do not pass local paths to
listenhub openapi video pixverse generate; ask the user for public URLs or prior PixVerse task/video IDs.
Step 0: Config Setup
Follow shared/config-pattern.md Step 0 (Zero-Question Boot).
If file doesn't exist — silently create with defaults and proceed:
mkdir -p ".listenhub/video-gen"
echo '{"outputMode":"inline"}' > ".listenhub/video-gen/config.json"
CONFIG_PATH=".listenhub/video-gen/config.json"
CONFIG=$(cat "$CONFIG_PATH")
Session defaults (not persisted unless user reconfigures):
- model:
happyhorse - resolution:
1080p - ratio:
16:9 - duration:
5
Do NOT ask any setup questions. Proceed directly to the Interaction Flow.
If file exists — read config silently and proceed:
CONFIG_PATH=".listenhub/video-gen/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/video-gen/config.json"
CONFIG=$(cat "$CONFIG_PATH")
Setup Flow (user-initiated reconfigure only)
Only run when the user explicitly asks to reconfigure. Display current settings:
当前配置 (video-gen):
输出方式: {outputMode}
Then ask:
- outputMode: Follow
shared/output-mode.md§ Setup Flow Question.
Save immediately:
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
Interaction Flow
Step 1: Collect Prompt
Ask the user for a video description. If they haven't provided one:
> 描述你想要生成的视频内容。
Free text input. Use as-is — do not modify the prompt unless the user asks for help.
Step 2: Mode Routing
Question: "你有参考素材想提供吗?"
Options:
- "没有,纯文字生成" — Text-to-video mode, skip to Step 4
- "有图片,想做首帧动画" — Image-to-video (first-frame) → Step 3a
- "有参考图片(风格/角色参考)" — Reference-image mode → Step 3b
- "有视频,想编辑/修改" — Video-edit mode → Step 3c
- "有视频,想做口型同步" — Lip-sync mode (PixVerse only) → Step 3d
If the user mentions PixVerse-exclusive capabilities (口型/lip sync, 模仿/mimic, restyle/风格化、融合/fusion、过渡/transition、广告/promo agent), route to PixVerse and pick the matching --capability — see Step 4 (PixVerse) and references/pixverse-api.md.
Step 3a: Image-to-Video (First-Frame)
- first-frame (required): Ask for the image path or URL.
- Supported formats: jpg, jpeg, png, webp
- Local image files max 10MB
- Image: width & height ≥ 300px, ratio between 1:2.5 and 2.5:1
- Local images: CLI auto-populates Seedance metadata. Remote Seedance image URLs require
--first-frame-meta WIDTHxHEIGHT[:SIZE].
- last-frame (optional, SeeDance only): If model is SeeDance, ask if there is a last-frame image.
Question: "有尾帧图片吗?(仅 SeeDance 支持)"
Options:
- "没有,只用首帧" — Skip last-frame
- "有" — Collect last-frame path/URL
After collecting, proceed to Step 4.
Note: HappyHorse i2v mode has no ratio parameter — ratio is determined by the input image. SeeDance still accepts --ratio.
Step 3b: Reference-Image Mode
Collect reference images (1–9 images required).
Ask for image paths/URLs:
- Supported formats: jpg, jpeg, png, webp
- Local image files max 10MB
- HappyHorse: short edge ≥ 400px recommended
- Local images: CLI auto-populates Seedance metadata. Remote Seedance image URLs require matching
--reference-image-meta WIDTHxHEIGHT[:SIZE]values.
HappyHorse prompt syntax: When multiple reference images are provided, the user can use [Image 1], [Image 2] etc. in the prompt to refer to specific images. Inform the user of this capability.
SeeDance additional references (only if model is SeeDance):
- reference-video (optional, max 3): mp4, mov, max 50MB
- reference-audio (optional, max 3): mp3, wav, max 20MB (must pair with image or video)
- reference-video metadata is required: provide
--reference-video-meta WIDTHxHEIGHT[:DURATION[:FPS[:SIZE]]]for each video.
After collecting, proceed to Step 4.
Step 3c: Video-Edit Mode (HappyHorse Only)
If model is SeeDance, inform the user: "视频编辑仅 HappyHorse 模型支持,已自动切换。" and set model to happyhorse.
- video (required): Ask for the video path or URL.
- Supported formats: mp4, mov (H.264 recommended)
- Duration: 3–60s (output capped at 15s)
- Max 100MB, ≥ 360px short edge, ≤ 4096px long edge
- URL only (no base64)
- reference-image (optional, 0–5): Ask if there are reference images for the edit.
- audio-setting:
Question: "音频如何处理?"
Options:
- "自动(模型决定)" — audio_setting: auto
- "保留原声" — audio_setting: origin
After collecting, proceed to Step 4.
Note: Video-edit has no ratio or duration parameters — output matches input video.
Step 3d: Lip-Sync Mode (PixVerse Only)
Lip sync is only available on PixVerse (--capability lip_sync). If the user is on HappyHorse/SeeDance, inform them: "口型同步仅 PixVerse 模型支持,已自动切换。" and use the PixVerse command template in Step 4.
- source video (required): the video whose lips will be driven. Collect EITHER:
--source-video-id— a PixVerse video id, OR--source-task-id— a prior succeeded PixVerse task to reuse.
(OpenAPI-only; the source must already exist on PixVerse.)
- audio source — ask the user which drive method:
Question: "口型用什么驱动?"
Options:
- "用一段音频文件" — Collect 1 audio URL → --audio
- "用文字转语音 (TTS)" — Collect speaker + content → --pixverse-json '{"tts":{...}}'
- Audio file: collect one public audio URL →
--audio(max 1),音频时长须落在 5–60s。 - TTS: collect a speaker id and the text to speak,走嵌套 JSON(不要用
--lip-sync-*flag,详见references/pixverse-api.md§ lip_sync): --pixverse-json '{"tts":{"speakerId":"","content":""}}'
Do NOT mix audio and TTS — pick one(同时给两者会被契约拒绝)。
After collecting, proceed to Step 4 (use the PixVerse lip_sync template).
Step 4: Optional Parameter Adjustment
Read session defaults and present. Adjust display based on mode:
For text-to-video and reference-image modes:
Question: "要调整生成参数吗?当前默认配置:\n 模型: happyhorse\n 分辨率: 1080p\n 比例: 16:9\n 时长: 5 秒"
Options:
- "用默认,直接生成" — Proceed to Step 5
- "我要调整参数" — Ask each parameter below
For image-to-video (first-frame) mode:
Question: "要调整生成参数吗?当前默认配置:\n 模型: happyhorse\n 分辨率: 1080p\n 时长: 5 秒"
Options:
- "用默认,直接生成" — Proceed to Step 5
- "我要调整参数" — Ask each parameter below
For video-edit mode: Skip Step 4 entirely — no adjustable generation params (only resolution).
If adjusting, ask each parameter one at a time:
Model:
Question: "模型?"
Options:
- "happyhorse(推荐)" — Higher quality, video-edit support
- "doubao-seedance-2-pro" — SeeDance pro, supports last-frame & audio ref
- "doubao-seedance-2-fast" — SeeDance fast
- "pixverse" — PixVerse: 口型同步/模仿/风格化/融合/过渡/广告 agent (OpenAPI only)
If the user picks pixverse, switch to the PixVerse command templates below — PixVerse uses its own … video pixverse generate namespace, an explicit --capability, and --quality/--aspect-ratio instead of --resolution/--ratio. See "PixVerse Command Templates" and references/pixverse-api.md.
Resolution:
Question: "分辨率?"
Options:
- "1080p(推荐)" — High quality (default for HappyHorse)
- "720p" — Standard quality
- "480p" — Low quality (SeeDance only)
Constraint: if user selects 480p and model is happyhorse, inform "HappyHorse 不支持 480p,已切换为 720p。" Constraint: if user selects 1080p and model is doubao-seedance-2-fast, silently upgrade to doubao-seedance-2-pro and inform "1080p 需要使用 pro 模型,已自动切换。"
Aspect ratio (not shown for i2v or video-edit):
Question: "画面比例?"
Options:
- "16:9" — Landscape, widescreen
- "9:16" — Portrait, phone screen
- "1:1" — Square
- "Other" — 4:3, 3:4, 4:5, 5:4 (4:5/5:4 HappyHorse only)
Duration:
Question: "时长?"
Options:
- "5 秒(推荐)" — Standard
- "8 秒" — Medium
- "10 秒" — Long
- "Other" — Custom (HappyHorse: 3–15, SeeDance: 4–15)
Seed (optional): Only ask if the user mentions wanting to reproduce a result. Otherwise skip.
Step 5: Cost Estimate + Execution Confirmation
Build and run the estimate command (no eval — direct invocation):
ESTIMATE=$($CMD_PREFIX estimate \
--model "happyhorse" \
--resolution "1080p" \
--duration 5 \
--ratio "16:9" \
--json 2>/tmp/lh-err)
EXIT_CODE=$?
For video-edit mode — add --has-video-input and --input-video-duration:
- If user provided a URL: ask duration
- Local files: detect with ffprobe as best-effort:
``bash INPUT_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "/path/to/ref.mp4" 2>/dev/null | cut -d. -f1) `` If ffprobe is unavailable or fails, skip estimate — show "预估不可用" in the summary.
ESTIMATE=$($CMD_PREFIX estimate \
--model "happyhorse" \
--resolution "1080p" \
--has-video-input \
--input-video-duration "$INPUT_DUR" \
--json 2>/tmp/lh-err)
EXIT_CODE=$?
Parse estimate result:
if [ $EXIT_CODE -eq 0 ]; then
TOKENS=$(echo "$ESTIMATE" | jq -r '.tokens // empty')
CREDITS=$(echo "$ESTIMATE" | jq -r '.credits // empty')
else
TOKENS=""
CREDITS=""
fi
rm -f /tmp/lh-err
Present confirmation summary:
Ready to generate video:
Prompt: {prompt text}
模式: {纯文字 / 首帧动画 / 参考图 / 视频编辑}
模型: {model}
分辨率: {resolution}
比例: {ratio or "跟随输入"}
时长: {duration} 秒 {or "跟随输入"}
素材: {无 / first-frame: path / references: N 个 / video: path}
预估费用: {tokens} tokens / {credits} credits ← or "预估不可用" if estimate failed
确认生成?
Wait for explicit confirmation before executing.
Execution & Polling
Submit (foreground)
Invoke $CMD_PREFIX create directly — never build a command string with eval. Substitute the actual collected values into the command. $CMD_PREFIX is either listenhub video (internal auth) or listenhub openapi video (A
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: joeseesun
- Source: joeseesun/qiaomu-cut-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.