tts/SKILL.md
Text-to-speech with edge-tts (primary, high-quality neural voices) and macOS say (fallback). Supports Korean, English, Japanese, and 40+ languages. Includes Telegram voice delivery workflow.
npx skillsauth add lidge-jun/cli-jaw-skills ttsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Tool | Quality | Languages | File Output | Use When | |------|---------|-----------|-------------|----------| | edge-tts (primary) | Neural, natural | 40+ | Fast, reliable | Default for all TTS tasks | | macOS say (fallback) | Robotic | ~30 | ⚠️ Hangs on Korean | English-only speaker output |
⚠️ macOS
say -ohangs indefinitely for Korean text. Always use edge-tts for Korean file output.
pip install edge-tts # In your project venv
brew install ffmpeg # For format conversion
Write a Python script (heredoc/inline causes encoding issues with non-ASCII text):
# /tmp/tts_gen.py
import asyncio, edge_tts
async def main():
text = "Hello! This is a test voice message from Jaw agent."
voice = "en-US-JennyNeural" # or "ko-KR-SunHiNeural" for Korean
comm = edge_tts.Communicate(text, voice)
await comm.save("/tmp/voice.mp3")
asyncio.run(main())
python3 /tmp/tts_gen.py
# Convert to OGG Opus (Telegram voice format)
ffmpeg -y -i /tmp/voice.mp3 -c:a libopus /tmp/voice.ogg
# Send via Bot API (use python requests — curl multipart may hang)
python3 /tmp/tg_voice.py
# /tmp/tg_voice.py
import json, os, requests
with open(os.path.expanduser("~/.cli-jaw/settings.json")) as f:
s = json.load(f)
token = s["telegram"]["token"]
chat_id = s["telegram"]["allowedChatIds"][-1]
with open("/tmp/voice.ogg", "rb") as f:
r = requests.post(
f"https://api.telegram.org/bot{token}/sendVoice",
data={"chat_id": chat_id, "caption": "Voice message"},
files={"voice": f}
)
print(r.status_code, r.json().get("ok"))
| Voice | Gender | Style |
|-------|--------|-------|
| ko-KR-SunHiNeural | Female | Friendly, natural |
| ko-KR-InJoonNeural | Male | Friendly, natural |
| ko-KR-HyunsuMultilingualNeural | Male | Multilingual capable |
| Voice | Gender | Style |
|-------|--------|-------|
| en-US-JennyNeural | Female | Natural, conversational |
| en-US-GuyNeural | Male | Natural, conversational |
| en-US-AriaNeural | Female | Professional |
| en-GB-SoniaNeural | Female | British |
| Voice | Gender |
|-------|--------|
| ja-JP-NanamiNeural | Female |
| ja-JP-KeitaNeural | Male |
edge-tts --list-voices # All voices
edge-tts --list-voices | grep ko-KR # Korean only
edge-tts --list-voices | grep en-US # US English only
comm = edge_tts.Communicate(
text,
"ko-KR-SunHiNeural",
rate="+20%", # Speed: -50% to +100%
pitch="+5Hz", # Pitch adjustment
volume="+0%" # Volume adjustment
)
ssml = """
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="en-US-JennyNeural">
<prosody rate="medium" pitch="medium">
Hello there. <break time="500ms"/> Pausing briefly before continuing.
</prosody>
</voice>
</speak>
"""
import asyncio, edge_tts
async def generate(text, output, voice="en-US-JennyNeural"):
comm = edge_tts.Communicate(text, voice)
await comm.save(output)
async def main():
tasks = [
generate("First message", "/tmp/msg1.mp3"),
generate("Second message", "/tmp/msg2.mp3"),
generate("Third in Korean", "/tmp/msg3.mp3", "ko-KR-SunHiNeural"),
]
await asyncio.gather(*tasks)
asyncio.run(main())
say (Fallback — English Only)say "Hello world" # Speak through speakers
say -v Samantha "Hello world" # Specific voice
say -r 200 "Fast speech" # Speed control
say -o /tmp/out.aiff "Hello world" # Save to file (English OK)
say -v '?' | grep en_ # List English voices
⚠️ macOS
say -ohangs indefinitely for Korean/CJK text. Use edge-tts for non-ASCII file output.
| Problem | Solution |
|---------|----------|
| edge-tts not found | pip install edge-tts in active venv |
| Korean say -o hangs | Use edge-tts instead |
| Telegram curl hangs | Use python requests instead |
| OGG conversion fails | brew install ffmpeg |
| Inline Python encoding error | Write to .py file first, then python3 file.py |
# 1. Generate → 2. Convert → 3. Send → 4. Cleanup
python3 /tmp/tts_gen.py
ffmpeg -y -i /tmp/voice.mp3 -c:a libopus /tmp/voice.ogg
python3 /tmp/tg_voice.py
rm /tmp/tts_gen.py /tmp/tg_voice.py /tmp/voice.mp3 /tmp/voice.ogg
development
Goal execution guidelines with PABCD integration, verification tiers, documentation workflow, and AI-driven planning
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
development
Use this skill any time a spreadsheet file is the primary input or output (.xlsx, .xlsm, .csv, .tsv). This includes: creating, reading, editing, analyzing, or formatting spreadsheets; cleaning messy tabular data; converting between formats; and data visualization with charts. Also use for pandas-based data analysis when the deliverable is a spreadsheet. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration.
tools
Use this skill when the user wants to build a financial model, 3-statement model, DCF valuation, cap table, scenario analysis, or financial projections in Excel. Trigger on: 'financial model', '3-statement model', 'DCF', 'cap table', 'pro forma', 'projections', 'sensitivity analysis', 'waterfall', 'debt schedule', 'break-even', 'discounted cash flow', 'capitalization table', 'fundraising model', 'WACC calculation', 'scenario analysis model'. Input is a text prompt with assumptions. Output is a single .xlsx file with formula-driven, interconnected statement sheets.