tts
Skill82 starsChanged 8 months agoMITView on GitHub
Text-to-speech and voice narration. Triggers on: "朗读这段", "配音", "TTS", "语音合成", "text to speech", "read this aloud", "convert to speech", "voice narration", "read aloud".
27 other projects use a version of this.
Adopted by
Most recently taken up by
- AxelGard/claude-une-tiradetheir own version, first seen Nov 8, 2026
- captjt/skill-ttstheir own version, first seen Nov 8, 2026
- pietz/skillstheir own version, first seen Nov 8, 2026
- codewhale-hq/codewhale-plugin-marketplacetheir own version, first seen Nov 8, 2026
- Leostruka/devin-bundletheir own version, first seen Nov 1, 2026
- momori777/Artemistheir own version, first seen Oct 22, 2026
Used with
Projects with it also use Video Generation, VLM and 9 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
huang-x-hSkillVideo Generation
Implement AI-powered video generation capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to generate videos from text prompts or images, create video content programmatically, or build applications that produce video outputs. Supports asynchronous task management with status polling and result retrieval.
Also in 6 projects that use this
huang-x-hSkillVLM
Implement vision-based AI chat capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to analyze images, describe visual content, or create applications that combine image understanding with conversational AI. Supports image URLs and base64 encoded images for multimodal interactions.
Also in 6 projects that use this
dav-niu474Skillgift-evaluator
The PRIMARY tool for Spring Festival gift analysis and social interaction generation. Use this skill when users upload photos of gifts (alcohol, tea, supplements, etc.) to inquire about their value, authenticity, or how to respond socially. Integrates visual perception, market valuation, and HTML card generation.
Also in 5 projects that use this
dav-niu474SkillPodcast Generate
Generate podcast episodes from user-provided content or by searching the web for specified topics. If user uploads a text file/article, creates a dual-host dialogue podcast (or single-host upon request). If no content is provided, searches the web for information about the user-specified topic and generates a podcast. Duration scales with content size (3-20 minutes, ~240 chars/min). Uses z-ai-web-dev-sdk for LLM script generation and TTS audio synthesis. Outputs both a podcast script (Markdown) and a complete audio file (WAV).
Also in 5 projects that use this
- +1 more from huang-x-h
- +6 more from dav-niu474
Other versions27 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 27
- jjyaoao/HelloAgents★ 3.2ksame name
- NoizAI/skills★ 526same name
- momori777/Artemis★ 437same name
- getsentry/junior★ 409same name
- crazynomad/skills★ 27same name
- sneakers-the-rat/muse-skills★ 24same name
- obra/muse-skills★ 20same name
- wpgaurav/WordPress-skills★ 19same name
- choupiyang/ZAI_SKILLS★ 13same name
- LocalKinAI/kinclaw★ 9same name
17 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- asrSkill
- cola-avatar-packSkill
- content-parserSkill
- creatorSkill
- explainerSkill
- google-calendarSkill
- icloud-calendarSkill
- image-genSkill
- listenhub-cliSkill
- listenhubSkill
- listenhub-voiceSkill
- musicSkill
- outlook-calendarSkill
- podcastSkill
- slidesSkill
- universal-emailSkill
- video-genSkill
- voice-cloneSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
28 rules. 0 are common, 8 are distinctive, and 20 are very specific to this project.
0
Common
Most of the 21 edited versions we read keep these.
8
Distinctive
This author's own choices. Worth a look.
20
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 37
Always check CLI auth following shared/cli-authentication.md
- Very specific: line 38
Follow shared/cli-patterns.md for CLI execution, errors, and interaction patterns
- Very specific: line 39
Never hardcode speaker IDs in CLI calls — use built-in defaults from shared/speaker-selection.md as fallback only.
- Very specific: line 40
Always read config following shared/config-pattern.md before any interaction
- Very specific: line 41
Always follow shared/speaker-selection.md for speaker selection (text table + free-text input)
- Very specific: line 42
Never save files to ~/Downloads/ or /tmp/ as primary output — save artifacts to the current working directory with friendly topic-based …
- Very specific: line 66
Follow shared/cli-authentication.md.
- Very specific: line 78
All subsequent CLI calls use $CMD_PREFIX instead of hardcoded listenhub tts.
- Very specific: line 82
Follow shared/config-pattern.md Step 0 (Zero-Question Boot).
- Distinctive: line 102
Only run when the user explicitly asks to reconfigure.
- Very specific: line 112
outputMode: Follow shared/output-mode.md § Setup Flow Question.
- Distinctive: line 119
After collecting answers, save immediately:
- Very specific: line 134
Only pass --speed when the user explicitly asks for a faster or slower reading — "慢一点"、"快一点"、"1.25 倍速"、"read it faster".
- Very specific: line 157
If config.defaultSpeakers.{language}[0] is set → use it silently (skip to Step 4)
- Very specific: line 158
If not set → use the built-in default from shared/speaker-selection.md for the detected language (skip to Step 4)
- Distinctive: line 159
Only show speaker selection if the user explicitly asks to change voice
- Distinctive: line 163
After the user explicitly selects a new voice (not when using defaults):
- Very specific: line 219
Read OUTPUT_MODE from config.
- Very specific: line 266
If config.defaultSpeakers.{language} has saved voices → auto-assign silently (one per character in order)
- Very specific: line 267
If not set → use built-in defaults from shared/speaker-selection.md (Primary for first character, Secondary for second)
- Distinctive: line 268
Only show speaker selection if the user explicitly asks to change voices
- Distinctive: line 272
After all voices are assigned (if any were new):
- Distinctive: line 339
When the background task completes, parse the result:
- Very specific: line 380
When saving preferences, merge into .listenhub/tts/config.json — do not overwrite unchanged keys.
- Very specific: line 407
Read config: defaultSpeakers.en is empty
- Very specific: line 408
Use built-in default: Mars (cozy-man-english)
- Very specific: line 423
Read config: defaultSpeakers.zh empty
- Distinctive: line 424
Use built-in defaults: 原野 (Primary) + 高晴 (Secondary)
“Common” is measured: kept by at least 6 in 10 of the 21 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
When to Use
- User wants to convert text to spoken audio
- User asks for "read aloud", "TTS", "text to speech", "voice narration"
- User says "朗读", "配音", "语音合成"
- User wants multi-speaker scripted audio or dialogue
When NOT to Use
- User wants a podcast-style discussion with topic exploration (use
/podcast) - User wants an explainer video with visuals (use
/explainer) - User wants to generate an image (use
/image-gen)
Purpose
Convert text into natural-sounding speech audio. Two paths:
- Quick mode (
--mode direct): Single voice, low-latency, sync. For casual chat, reading snippets, instant audio. - Script mode (
--mode smart): Multi-speaker, per-segment voice assignment. For dialogue, audiobooks, scripted content.
Hard Constraints
- Always check CLI auth following
shared/cli-authentication.md - Follow
shared/cli-patterns.mdfor CLI execution, errors, and interaction patterns - Never hardcode speaker IDs in CLI calls — use built-in defaults from
shared/speaker-selection.mdas fallback only; fetch from the speakers CLI when the user wants to change voice - Always read config following
shared/config-pattern.mdbefore any interaction - Always follow
shared/speaker-selection.mdfor speaker selection (text table + free-text input) - Never save files to
~/Downloads/or/tmp/as primary output — save artifacts to the current working directory with friendly topic-based names (seeshared/config-pattern.md§ Artifact Naming)
<HARD-GATE>
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 any generation CLI command until the user has explicitly confirmed.</HARD-GATE>Mode Detection
Determine the mode from the user's input automatically before asking any questions:
| Signal | Mode |
| "多角色", "脚本", "对话", "script", "dialogue", "multi-speaker" | Script |
| Multiple characters mentioned by name or role | Script |
| Input contains structured segments (A: ..., B: ...) | Script |
| Single paragraph of text, no character markers | Quick |
| "读一下", "read this", "TTS", "朗读" with plain text | Quick |
| Ambiguous | Quick (default) |
Interaction Flow
Step -1: CLI Auth Check
Follow shared/cli-authentication.md. If the CLI is not installed or the user is not logged in, auto-install and auto-login — never ask the user to run commands manually.
Then follow shared/cli-authentication.md § Auth Mode Detection to determine AUTH_MODE and set:
if [ "$AUTH_MODE" = "openapi" ]; then
CMD_PREFIX="listenhub openapi tts"
else
CMD_PREFIX="listenhub tts"
fiAll subsequent CLI calls use $CMD_PREFIX instead of hardcoded listenhub tts.
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/tts"
echo '{"outputMode":"inline","language":null,"defaultSpeakers":{}}' > ".listenhub/tts/config.json"
CONFIG_PATH=".listenhub/tts/config.json"
CONFIG=$(cat "$CONFIG_PATH")Do NOT ask any setup questions. Proceed directly to the Interaction Flow.
If file exists — read config silently and proceed:
CONFIG_PATH=".listenhub/tts/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/tts/config.json"
CONFIG=$(cat "$CONFIG_PATH")Setup Flow (user-initiated reconfigure only)
Only run when the user explicitly asks to reconfigure. Display current settings:
当前配置 (tts):
输出方式:{inline / download / both}
语言偏好:{zh / en / 未设置}
默认主播:{speakerName / 使用内置默认}Then ask:
- outputMode: Follow
shared/output-mode.md§ Setup Flow Question. - Language (optional): "默认语言?"
- "中文 (zh)"
- "English (en)"
- "每次手动选择" → keep
null
After collecting answers, save immediately:
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
# Save language if user chose one (not "每次手动选择")
if [ "$LANGUAGE" != "null" ]; then
NEW_CONFIG=$(echo "$NEW_CONFIG" | jq --arg lang "$LANGUAGE" '. + {"language": $lang}')
fi
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")Generation Speed
Default: 1.0x (original speed). Never ask about speed.
Only pass --speed when the user explicitly asks for a faster or slower reading —
"慢一点"、"快一点"、"1.25 倍速"、"read it faster". Otherwise omit the flag.
- Range: any value from
0.5to2.0, at most two decimals — a continuous range, not fixed steps. - Common values:
0.5,0.75,1(default),1.25,1.5,2; in-between values such as0.85or1.35work too. - Meaning: the speaking rate of the generated audio, not a player playback rate.
- Map vague wording conservatively: "慢一点" →
0.85, "快一点" →1.25, "慢很多" →0.5, "快很多" →1.75. A number the user names is passed through unchanged.
Show the speed in the confirmation summary only when it is not 1.
Quick Mode — $CMD_PREFIX create --mode direct
Step 1: Extract text
Get the text to convert. If the user hasn't provided it, ask:
"What text would you like me to read aloud?"
Step 2: Determine voice
- If
config.defaultSpeakers.{language}[0]is set → use it silently (skip to Step 4) - If not set → use the built-in default from
shared/speaker-selection.mdfor the detected language (skip to Step 4) - Only show speaker selection if the user explicitly asks to change voice
Step 3: Save preference
After the user explicitly selects a new voice (not when using defaults):
Question: "Save {voice name} as your default voice for {language}?"
Options:
- "Yes" — update .listenhub/tts/config.json
- "No" — use for this session onlyStep 4: Confirm
Ready to generate:
Text: "{first 80 chars}..."
Voice: {voice name}
Speed: {speed}x # omit this line when speed is 1
Proceed?Step 5: Generate
For short text, pass inline:
RESULT=$($CMD_PREFIX create --text "{text}" --mode direct --speaker "{name}" --lang {lang} [--speed {0.5-2.0}] --json 2>/tmp/lh-err)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
ERROR=$(cat /tmp/lh-err)
case $EXIT_CODE in
2) echo "Auth error: run 'listenhub auth login'" ;;
3) echo "Timeout: try --no-wait" ;;
*) echo "Error: $ERROR" ;;
esac
rm -f /tmp/lh-err
fi
rm -f /tmp/lh-err
AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')For long text, write to a temp file first (see shared/cli-patterns.md § Long Text Input):
cat > /tmp/lh-content.txt << 'ENDCONTENT'
Long text content goes here...
ENDCONTENT
RESULT=$($CMD_PREFIX create --text "$(cat /tmp/lh-content.txt)" --mode direct --speaker "{name}" --lang {lang} [--speed {0.5-2.0}] --json)
AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')
rm -f /tmp/lh-content.txtStep 6: Present result
Read OUTPUT_MODE from config. Follow shared/output-mode.md for behavior.
inline or both: Display the audioUrl as a clickable link.
Present:
Audio generated!
在线收听:{audioUrl}download or both: Also download the file. Generate a topic slug from the text content following shared/config-pattern.md § Artifact Naming.
SLUG="{topic-slug}" # e.g. "server-maintenance-notice"
NAME="${SLUG}.mp3"
# Dedup: if file exists, append -2, -3, etc.
BASE="${NAME%.*}"; EXT="${NAME##*.}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$AUDIO_URL"Present:
Audio generated!
已保存到当前目录:
{NAME}Script Mode — $CMD_PREFIX create --mode smart
Step 1: Get scripts
Determine whether the user already has a scripts array:
- Already provided (JSON or clear segments): parse and display for confirmation
Not yet provided: help the user structure segments. Ask:
"Please provide the script with speaker assignments. Format: each line as
SpeakerName: text content. I'll convert it."Once the user provides the script, parse it into speaker-annotated text.
Step 2: Assign voices per character
For each unique character in the script:
- If
config.defaultSpeakers.{language}has saved voices → auto-assign silently (one per character in order) - If not set → use built-in defaults from
shared/speaker-selection.md(Primary for first character, Secondary for second) - Only show speaker selection if the user explicitly asks to change voices
Step 3: Save preferences
After all voices are assigned (if any were new):
Question: "Save these voice assignments for future sessions?"
Options:
- "Yes" — update defaultSpeakers in .listenhub/tts/config.json
- "No" — use for this session onlyStep 4: Confirm
Ready to generate:
Characters:
{name}: {voice}
{name}: {voice}
Segments: {count}
Speed: {speed}x # omit this line when speed is 1
Title: (auto-generated)
Proceed?Step 5: Generate
Format the script text with speaker markers and submit. For multi-speaker scripts, include speaker names inline in the text. Run with run_in_background: true since script mode may take longer.
Submit (foreground) with --no-wait:
RESULT=$($CMD_PREFIX create --text "{formatted script with speaker markers}" --mode smart --speaker "{name1}" --speaker "{name2}" --lang {lang} [--speed {0.5-2.0}] --no-wait --json)
ID=$(echo "$RESULT" | jq -r '.id')
echo "Submitted: $ID"For long scripts, write to a temp file first:
cat > /tmp/lh-content.txt << 'ENDCONTENT'
SpeakerA: First line of dialogue
SpeakerB: Second line of dialogue
...
ENDCONTENT
RESULT=$($CMD_PREFIX create --text "$(cat /tmp/lh-content.txt)" --mode smart --speaker "{name1}" --speaker "{name2}" --lang {lang} [--speed {0.5-2.0}] --no-wait --json)
ID=$(echo "$RESULT" | jq -r '.id')
rm -f /tmp/lh-content.txtPoll (background) with run_in_background: true and timeout: 600000:
ID="<id-from-above>"
for i in $(seq 1 60); do
RESULT=$(listenhub creation get "$ID" --json 2>/dev/null)
STATUS=$(echo "$RESULT" | jq -r '.status // "processing"')
case "$STATUS" in
completed) echo "$RESULT"; exit 0 ;;
failed) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2Step 6: Present result
When the background task completes, parse the result:
AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')
SUBTITLES_URL=$(echo "$RESULT" | jq -r '.subtitlesUrl // empty')
DURATION=$(echo "$RESULT" | jq -r '.audioDuration // empty')
CREDITS=$(echo "$RESULT" | jq -r '.credits // empty')Read OUTPUT_MODE from config. Follow shared/output-mode.md for behavior.
inline or both: Display the audioUrl and subtitlesUrl as clickable links.
Present:
Audio generated!
在线收听:{audioUrl}
字幕:{subtitlesUrl}
时长:{audioDuration / 1000}s
消耗积分:{credits}download or both: Also download the file. Generate a topic slug following shared/config-pattern.md § Artifact Naming.
SLUG="{topic-slug}" # e.g. "welcome-dialogue"
NAME="${SLUG}.mp3"
# Dedup: if file exists, append -2, -3, etc.
BASE="${NAME%.*}"; EXT="${NAME##*.}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$AUDIO_URL"Present:
已保存到当前目录:
{NAME}Updating Config
When saving preferences, merge into .listenhub/tts/config.json — do not overwrite unchanged keys.
- Quick voice: set
defaultSpeakers.{language}[0]to the selectedspeakerId - Script voices: set
defaultSpeakers.{language}to the full array assigned this session - Language: set
languageif the user explicitly specifies it
API Reference
- CLI execution patterns:
shared/cli-patterns.md - CLI authentication:
shared/cli-authentication.md - Speaker list:
shared/cli-speakers.md - Speaker selection guide:
shared/speaker-selection.md - Config pattern:
shared/config-pattern.md - Output mode:
shared/output-mode.md
Composability
- Invokes: speakers CLI (for speaker selection)
- Invoked by: explainer (for voiceover)
Examples
Quick mode:
"TTS this: The server will be down for maintenance at midnight."
- Detect: Quick mode (plain text, "TTS this")
- Read config:
defaultSpeakers.enis empty - Use built-in default: Mars (
cozy-man-english) - Confirm → user approves
- Generate:
RESULT=$($CMD_PREFIX create --text "The server will be down for maintenance at midnight." --mode direct --speaker "Mars" --lang en --json) AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl') - Present: display
audioUrlas link (inline mode)
Script mode:
"帮我做一段双人对话配音,A说:欢迎大家,B说:谢谢邀请"
- Detect: Script mode ("双人对话")
- Parse segments: A -> "欢迎大家", B -> "谢谢邀请"
- Read config:
defaultSpeakers.zhempty - Use built-in defaults: 原野 (Primary) + 高晴 (Secondary)
- Confirm → user approves
- Generate:
RESULT=$($CMD_PREFIX create --text "A: 欢迎大家 B: 谢谢邀请" --mode smart --speaker "原野" --speaker "高晴" --lang zh --no-wait --json) ID=$(echo "$RESULT" | jq -r '.id') - Poll in background until complete
- Present:
audioUrl,subtitlesUrl, duration
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

