بنقرة واحدة
gen-tts
Synthesize speech audio via Gemini 3.1 Flash TTS — single clip, batch parallel, voice + style presets
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Synthesize speech audio via Gemini 3.1 Flash TTS — single clip, batch parallel, voice + style presets
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Surface open PRs that have genuinely unaddressed review feedback, filtering out CodeRabbit auto-summaries and CI-bot noise. Use before ending a session, when asked "which of my PRs need attention", or to gate a session close on unresolved review threads.
Sync git repository with upstream. Use at the start of a session, when asked to sync, get up to date, check git status, or when working on a stale branch.
Analyze content and generate illustrations via Gemini image API
Brainstorm multiple visual directions for a blog image, generate them in parallel, build a comparison page, and optionally publish as a shareable link (Surge.sh or gist).
Bulk-parallel CLIs — turn N sequential gh/bd/git/file tool calls into a single fan-out JSON call. Use when the session is about to fire ≥3 similar sequential calls (gh pr view, bd show, Read of small files, up-to-date diagnose across repos).
Extract durable lessons from a completed Claude session and codify them in the right CLAUDE.md files or skills. Use at the end of a long session, after a bug hunt that surfaced a non-obvious constraint, or when the user asks "what can we learn from this session". Discovers CLAUDE.md files dynamically, routes lessons by generic scope (project / shared conventions / environment / machine-local), enforces neutral voice, and asks for approval before editing.
| name | gen-tts |
| description | Synthesize speech audio via Gemini 3.1 Flash TTS — single clip, batch parallel, voice + style presets |
| argument-hint | single --text <text> --output path.wav | batch file.json [--voice NAME] [--style-preset NAME] |
| allowed-tools | Bash, Read, Write, Glob, Grep, AskUserQuestion |
Turn text into natural-sounding speech via Google's Gemini 3.1 Flash TTS
preview. Supports single-clip generation, parallel batch mode, prosody
tags ([whisper], [short pause], [excited], …), and voice preset
files.
Parse the user's input for:
--text-file)--voice NAME: Voice preset name. Resolves in this order:
voices/<NAME>.txt in this skill dir — first non-comment line is the literal Gemini voiceName (for single-line voice-ID presets)Kore, Puck, Charon) passed straight throughtts-voice.txt (Charon ships as the default)--style-prompt TEXT: Director's-notes prefix prepended to the text (e.g. "Speak slowly, with a warm Newcastle accent."). Gemini honors these notes separately from the voice ID.--style-preset NAME: Load a multi-line style directive from voices/<NAME>.txt (e.g. freud, soprano). Comment lines stripped, body collapsed to one paragraph, prepended as a director's note. Mutually exclusive with --style-prompt / --style-file.--style-file PATH: Like --style-preset but takes an explicit file path (for styles kept outside the skill dir).--output path.wav: Where to save the WAV file--speed FLOAT: Post-process tempo multiplier applied via ffmpeg atempo after the Gemini call. 1.0 (default) = no change, 1.8 pairs well with the freud preset (the preset is deliberately slow; speeding to 1.8× tightens the phrasing without losing the character). Quality is best in [0.5, 2.0]; values outside that band chain atempo filters automatically. Gemini 3.1 Flash TTS has no server-side speed parameter, so post-processing is the deterministic path. Requires ffmpeg on PATH.batch file.json: Parallel batch mode subcommand (see shape below)--api-url URL: Override the Gemini endpoint (rarely needed; useful for testing against a proxy)--voice (Gemini voice ID) and --style-* (director's notes prepended to
the text) are independent and compose — e.g. --voice Charon --style-preset freud pairs the Charon baritone with Freud's Viennese pacing.
GOOGLE_API_KEY — auto-loaded from ~/.env by generate-tts.py (same var as gen-image). Passed as an x-goog-api-key header so the key never leaks into URL access logs, shell traces, or proxy logs.tts-voice.txt in this skill's directorygenerate-tts.py — handles the HTTP call, WAV assembly, env loading, voice resolution, and parallel batch execution. Stdlib core with Typer for CLI (no requests / httpx / jq / curl deps); the PEP-723 shebang (#!/usr/bin/env -S uv run --script) means it runs without a local venv. Two subcommands: single (one clip) and batch (parallel from JSON manifest).gemini-3.1-flash-tts-previewPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-tts-preview:generateContentcandidates[0].content.parts[*].inlineData.data. generate-tts.py
wraps it in a canonical WAV header (via struct.pack) so the .wav
output is directly playable by any audio tool. Sample rate is parsed
from the response MIME type (audio/L16;codec=pcm;rate=24000) with
24000 as the fallback.Embed these inline in the text to steer delivery (Gemini interprets them rather than speaking them verbatim):
[whisper], [shouting], [sigh], [gasp],
[laughs], [crying][short pause], [long pause][excited], [tired], [sarcastic], [amazed],
[angry], [confused], [nervous], [calm], [warm]The model also accepts narrative "director's notes" prefixed to the
text — e.g. "Speak slowly, with a warm Newcastle accent: <text>" — per
Simon Willison's 2026-04-15 write-up. Use either approach; they compose.
30 prebuilt voices ship with the model. Ones we've found useful:
| Voice | Vibe | Use for |
|---|---|---|
Charon (default) | Deeper storyteller baritone | Larry-style grounding, long-form narration |
Kore | Firm, observer-coach (reads feminine) | Review reads when that vibe fits |
Puck | Upbeat, playful | Kickoff messages, celebratory clips |
Aoede | Warm, soft | Empathic/comfort lines |
Full catalog in tts-voice.txt. To lock in a named preset separately
from the default, drop voices/<name>.txt next to this file with the
literal voiceName on its first non-comment line.
voices/<name>.txt — two shapesFiles in voices/ serve two distinct purposes:
Kore, Charon, Puck, etc.). Used via
--voice <name>. The rest of the file is commentary on when to pick it.--style-preset <name>. Comment lines are stripped; the body is
prepended to the text as a director's note. These do NOT pick a
Gemini voice — pair them with --voice Charon (or whichever voice
ID suits the character) for best results.Shipped style presets: freud, soprano.
The script is executable and uses a uv-powered PEP-723 shebang — invoke it directly, no python3 prefix needed:
GEN_TTS="$(git -C ~/gits/chop-conventions rev-parse --show-toplevel)/skills/gen-tts/generate-tts.py"
"$GEN_TTS" single --text "Hello from Larry. [short pause] This is a voice pipeline test." --output /tmp/larry.wav
"$GEN_TTS" single --text-file /tmp/script.txt --output /tmp/read.wav --voice Charon
echo "piped text" | "$GEN_TTS" single --output /tmp/piped.wav
# Freud's Viennese analyst voice, baritone
"$GEN_TTS" single --text "Tell me about your mother." --voice Charon \
--style-preset freud --output /tmp/freud.wav
# Freud at 1.8× — same deliberate phrasing, tighter tempo
"$GEN_TTS" single --text "Tell me about your mother." --voice Charon \
--style-preset freud --speed 1.8 --output /tmp/freud-fast.wav
# Inline director's notes (no preset)
"$GEN_TTS" single --text "Welcome aboard." --voice Puck \
--style-prompt "Speak with the warmth of a flight attendant greeting family." \
--output /tmp/welcome.wav
Write a JSON file:
[
{
"text": "Good morning. [short pause] Ready to start?",
"output": "/tmp/morning.wav",
"voice": "Kore"
},
{
"text": "[excited] You nailed that workout!",
"output": "/tmp/celebrate.wav",
"voice": "Puck"
},
{ "text": "[whisper] Time to wind down.", "output": "/tmp/bedtime.wav" },
{
"text": "Tell me about your father.",
"output": "/tmp/freud.wav",
"voice": "Charon",
"style_preset": "freud"
}
]
Each job object accepts text, output, voice, plus any one of
style_prompt / style_preset / style_file, plus an optional speed
float. A --style-* or --speed flag on the CLI provides a default that
per-job entries can override.
Then:
"$GEN_TTS" batch /tmp/lines.json --max-workers 4
_duration_s is written back into each job object for debug visibility. The batch file is rewritten atomically (tempfile + os.replace) so a crash mid-write never corrupts the input.
~/.env. If still unset, set GOOGLE_API_KEY in env or ~/.env.error.message (malformed request, quota exhausted, billing not enabled, TTS preview not enabled) is surfaced verbatim with an API Error: prefix.promptFeedback.blockReason surfaces as Gemini TTS refused the prompt (blockReason=...) with the specific reason (e.g. PROHIBITED_CONTENT) plus any safetyRatings for diagnosis.candidates[0].finishReason of SAFETY / PROHIBITED_CONTENT / RECITATION / OTHER (anything other than STOP / MAX_TOKENS) surfaces as refused to generate audio (finishReason=...). Most common trigger: certain prosody tags ([excited], [whisper]) combined with flavorful content trip the filter. Retry without the tag or rephrase.HTTP request failed after retry: ....urllib.request, base64, struct, json). No jq / curl / requests / httpx required — just a Python 3.11+ interpreter managed by uv (the PEP-723 shebang bootstraps it)./tmp/ or the consumer repo's assets dir.