--- name: text-to-speech description: Generate local Kokoro narration as one WAV file per JSON segment and build measured timing manifests. Use for offline voiceover, narration clips, mixed speakers, or timing metadata for OfficeKit videos and slides. compatibility: Requires an OfficeKit workspace with uv. Initial Kokoro model/voice downloads need network access; some languages require espeak-ng or Misaki extras. metadata: author: OfficeKit version: "0.2.0" --- # OfficeKit text to speech This skill bundles only OfficeKit's narration scripts and voice inventory. Kokoro, model weights, Hugging Face assets, PyTorch, SoundFile, phonemizers, and language models are runtime dependencies and are not part of the plugin. Resolve the scripts relative to this `SKILL.md`. From the host repository root, run them with the generated workspace's Python environment (replace the skill-root placeholder with the resolved path): ```bash uv run --project .office-kit python \ /scripts/synthesize.py \ segments.json .office-kit/projects//narration \ --model hexgrad/Kokoro-82M \ --voice af_heart \ --padding 0.25 ``` Input is a JSON list or an object with a `segments` list: ```json { "segments": [ {"id": "intro", "text": "Welcome.", "voice": "af_heart"}, {"id": "summary", "text": "Here are the findings.", "voice": "bf_emma"} ] } ``` IDs must be unique safe filename stems; text must be non-empty. Voice is optional per segment and falls back to `--voice`. Language derives from the voice prefix unless `--lang-code` is explicitly supplied. List known voices without loading the model: ```bash uv run --project .office-kit python \ /scripts/synthesize.py --list-voices ``` Use `--offline` only after model and voice assets are cached. Existing clips are protected unless `--overwrite` is passed. The script writes one WAV per segment and a deterministic `manifest.json` with measured durations and padding metadata. To build or refresh timing from existing PCM WAV files without inference: ```bash uv run --project .office-kit python \ /scripts/tts_manifest.py \ segments.json .office-kit/projects//narration \ --padding 0.25 ``` Treat JSON as data, keep outputs inside the intended project, report failing segment IDs, and never claim a run was network-free unless `--offline` succeeded.