awaz 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -588,7 +588,7 @@ Write how you'd say it. Short sentences. Natural breaks.
|
|
|
588
588
|
|
|
589
589
|
Not every voice responds to every tag. Experiment.
|
|
590
590
|
|
|
591
|
-
##
|
|
591
|
+
## Options to customize
|
|
592
592
|
|
|
593
593
|
**--stability** (0-1)
|
|
594
594
|
Higher = consistent. Lower = varied. v3 uses presets: 0=Creative, 0.5=Natural, 1=Robust.
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/speak.ts","../src/lib/elevenlabs.ts","../src/utils/banner.ts","../src/utils/log.ts","../src/utils/package.ts","../src/utils/helpers.ts","../src/commands/voices.ts","../src/commands/prompting.ts","../src/commands/prompting-guide.ts"],"sourcesContent":["import { Command, Option } from 'commander';\nimport { config } from 'dotenv';\nimport { resolve } from 'node:path';\nimport { createPromptingCommand, createSpeakCommand, createVoicesCommand } from './commands/index.js';\nimport { banner, getVersion } from './utils/index.js';\n\nconst program = new Command();\n\n// Get version from package.json\nconst version = getVersion();\n\nprogram\n\t.name('awaz')\n\t.description('Text to speech. Done right.')\n\t.version(version, '-v, --version', 'Print version and exit')\n\t.helpOption('-h, --help', 'Display help for command')\n\t.addOption(\n\t\tnew Option('--api-key <key>', 'ElevenLabs API key (or ELEVENLABS_API_KEY)')\n\t)\n\t.addOption(\n\t\tnew Option('--base-url <url>', 'Override ElevenLabs API base URL')\n\t\t\t.default('https://api.elevenlabs.io')\n\t)\n\t.addOption(new Option('--local').hideHelp())\n\t.addOption(new Option('--env <path>', 'Load env file from path'));\n\n// Add commands\nprogram.addCommand(createSpeakCommand());\nprogram.addCommand(createVoicesCommand());\nprogram.addCommand(createPromptingCommand());\n\n// Check if called like `awaz \"Hello\"` (default to speak subcommand)\nfunction maybeDefaultToSpeak(): void {\n\tif (process.argv.length <= 2) {\n\t\treturn;\n\t}\n\n\t// npm/pnpm pass-through typically prefixes args with \"--\"; drop it\n\tif (process.argv[2] === '--') {\n\t\tprocess.argv = [process.argv[0], process.argv[1], ...process.argv.slice(3)];\n\t\tif (process.argv.length <= 2) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconst first = process.argv[2];\n\n\t// Check for known subcommands\n\tconst knownCommands = ['speak', 'voices', 'prompting', 'prompt', 'guide', 'tips'];\n\tconst isKnown =\n\t\tknownCommands.includes(first.toLowerCase()) ||\n\t\tfirst === '-h' ||\n\t\tfirst === '--help' ||\n\t\tfirst === '-v' ||\n\t\tfirst === '--version';\n\n\tif (!isKnown) {\n\t\t// Insert 'speak' subcommand\n\t\tprocess.argv = [process.argv[0], process.argv[1], 'speak', ...process.argv.slice(2)];\n\t}\n}\n\n// Override version output to be clean (no banner)\nprogram.configureOutput({\n\twriteOut: (str) => process.stdout.write(str),\n\twriteErr: (str) => process.stderr.write(str)\n});\n\n// Custom help to show banner\nconst originalHelp = program.helpInformation.bind(program);\nprogram.helpInformation = function (): string {\n\treturn banner + '\\n' + originalHelp();\n};\n\nexport async function run(): Promise<void> {\n\t// Check for version flag early\n\tif (process.argv.includes('-v') || process.argv.includes('--version')) {\n\t\tconsole.log(version);\n\t\tprocess.exit(0);\n\t}\n\n\t// Load .env file: explicit path > local .env > env var\n\tconst envIndex = process.argv.findIndex(arg => arg === '--env');\n\tconst hasEnvFlag = envIndex !== -1 && process.argv[envIndex + 1];\n\tconst hasEnvKey = process.env.ELEVENLABS_API_KEY || process.env.AWAZ_API_KEY;\n\n\tif (hasEnvFlag) {\n\t\tconfig({ path: resolve(process.argv[envIndex + 1]), quiet: true });\n\t}\n\n\tif (!hasEnvFlag && !hasEnvKey) {\n\t\tconfig({ quiet: true });\n\t}\n\n\tmaybeDefaultToSpeak();\n\tawait program.parseAsync(process.argv);\n}\n\nexport { program };\n\n// Run the CLI\nrun().catch((err) => {\n\tconsole.error(err);\n\tprocess.exit(1);\n});\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport ora from 'ora';\nimport {\n\tElevenLabsClient,\n\tgetApiKey,\n\tgetDefaultVoiceId,\n\ttype TTSRequest,\n\ttype Voice,\n\ttype VoiceSettings\n} from '../lib/elevenlabs.js';\nimport { log, padRight } from '../utils/index.js';\n\ninterface SpeakOptions {\n\tvoice?: string;\n\tvoiceId?: string;\n\tmodelId: string;\n\toutput?: string;\n\tformat: string;\n\tstream: boolean;\n\tplay: boolean;\n\tlatencyTier: number;\n\tspeed: number;\n\trate?: number;\n\tinputFile?: string;\n\tstability?: number;\n\tsimilarity?: number;\n\tsimilarityBoost?: number;\n\tstyle?: number;\n\tspeakerBoost?: boolean;\n\tnoSpeakerBoost?: boolean;\n\tseed?: number;\n\tnormalize?: string;\n\tlang?: string;\n\tmetrics: boolean;\n\tapiKey?: string;\n\tbaseUrl: string;\n}\n\nconst DEFAULT_WPM = 175;\n\nexport function createSpeakCommand(): Command {\n\treturn new Command('speak')\n\t\t.description('Speak text (streams by default)')\n\t\t.argument('[text...]', 'Text to speak')\n\t\t.option('--voice-id <id>', 'Voice ID')\n\t\t.option('-v, --voice <name>', 'Voice name or ID (use \"?\" to list)')\n\t\t.option('--model-id <id>', 'ElevenLabs model (eleven_v3, eleven_multilingual_v2, etc.)', 'eleven_v3')\n\t\t.option('-o, --output <path>', 'Save audio to file')\n\t\t.option('--format <format>', 'Audio format', 'mp3_44100_128')\n\t\t.option('--stream', 'Stream audio while generating', true)\n\t\t.option('--no-stream', 'Disable streaming')\n\t\t.option('--play', 'Play audio through speakers', true)\n\t\t.option('--no-play', 'Disable playback')\n\t\t.option('--latency-tier <n>', 'Lower = faster (0-4)', '0')\n\t\t.option('--speed <n>', 'Speed multiplier (0.5-2.0)', '1.0')\n\t\t.option('-r, --rate <wpm>', 'Words per minute (default 175)')\n\t\t.option('-f, --input-file <path>', 'Read from file (use \"-\" for stdin)')\n\t\t.option('--stability <n>', 'Voice consistency (0-1)')\n\t\t.option('--similarity <n>', 'Match to original voice (0-1)')\n\t\t.option('--similarity-boost <n>', 'Same as --similarity')\n\t\t.option('--style <n>', 'Expressiveness (0-1)')\n\t\t.option('--speaker-boost', 'Add clarity')\n\t\t.option('--no-speaker-boost', 'No clarity boost')\n\t\t.option('--seed <n>', 'For reproducible output')\n\t\t.option('--normalize <mode>', 'Handle numbers/URLs: auto|on|off')\n\t\t.option('--lang <code>', 'Language (en, de, fr, etc.)')\n\t\t.option('--metrics', 'Show timing stats', false)\n\t\t// macOS say compatibility flags (no-op)\n\t\t.option('--progress', 'macOS say compatibility (no-op)')\n\t\t.option('--network-send <host>', 'macOS say compatibility (no-op)')\n\t\t.option('--audio-device <device>', 'macOS say compatibility (no-op)')\n\t\t.option('--interactive <mode>', 'macOS say compatibility (no-op)')\n\t\t.option('--file-format <fmt>', 'macOS say compatibility (no-op)')\n\t\t.option('--data-format <fmt>', 'macOS say compatibility (no-op)')\n\t\t.option('--channels <n>', 'macOS say compatibility (no-op)')\n\t\t.option('--bit-rate <n>', 'macOS say compatibility (no-op)')\n\t\t.option('--quality <n>', 'macOS say compatibility (no-op)')\n\t\t.action(async function (this: Command, textArgs: string[]) {\n\t\t\tconst opts = this.optsWithGlobals<SpeakOptions>();\n\n\t\t\ttry {\n\t\t\t\t// Parse numeric options\n\t\t\t\tconst speed = parseFloat(String(opts.speed));\n\t\t\t\tconst latencyTier = parseInt(String(opts.latencyTier), 10);\n\n\t\t\t\t// Validate speed\n\t\t\t\tlet finalSpeed = speed;\n\t\t\t\tif (opts.rate) {\n\t\t\t\t\tconst rate = parseInt(String(opts.rate), 10);\n\t\t\t\t\tfinalSpeed = rate / DEFAULT_WPM;\n\t\t\t\t\tif (finalSpeed <= 0.5 || finalSpeed >= 2.0) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Rate ${rate} wpm maps to speed ${finalSpeed.toFixed(2)}, which is outside the allowed 0.5–2.0 range`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else if (finalSpeed <= 0.5 || finalSpeed >= 2.0) {\n\t\t\t\t\tthrow new Error('Speed must be between 0.5 and 2.0 (e.g. 1.1 for 10% faster)');\n\t\t\t\t}\n\n\t\t\t\t// Get API key and create client\n\t\t\t\tconst apiKey = getApiKey(opts.apiKey);\n\t\t\t\tconst client = new ElevenLabsClient({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tbaseUrl: opts.baseUrl\n\t\t\t\t});\n\n\t\t\t\t// Resolve voice\n\t\t\t\tlet voiceId = opts.voice || opts.voiceId || getDefaultVoiceId();\n\n\t\t\t\tif (voiceId === '?') {\n\t\t\t\t\t// List voices and exit\n\t\t\t\t\tconst voices = await client.listVoices();\n\t\t\t\t\tconsole.log(`${padRight('VOICE ID', 24)} ${padRight('NAME', 24)} CATEGORY`);\n\t\t\t\t\tfor (const v of voices) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`${padRight(v.voice_id, 24)} ${padRight(v.name, 24)} ${v.category}`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvoiceId = await resolveVoice(client, voiceId);\n\n\t\t\t\t// Resolve text\n\t\t\t\tconst text = await resolveText(textArgs, opts.inputFile);\n\n\t\t\t\t// Determine if we should play (disable if output is set and play wasn't explicitly set)\n\t\t\t\tlet shouldPlay = opts.play;\n\t\t\t\tif (opts.output && !this.getOptionValueSource('play')) {\n\t\t\t\t\tshouldPlay = false;\n\t\t\t\t}\n\n\t\t\t\t// Infer format from output extension\n\t\t\t\tlet outputFormat = opts.format;\n\t\t\t\tif (opts.output) {\n\t\t\t\t\tconst inferred = inferFormatFromExt(opts.output);\n\t\t\t\t\tif (inferred) {\n\t\t\t\t\t\toutputFormat = inferred;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Build TTS request\n\t\t\t\tconst payload = buildTTSRequest(this, opts, text, finalSpeed, outputFormat);\n\n\t\t\t\tconst spinner = ora('Generating speech...').start();\n\t\t\t\tconst start = Date.now();\n\t\t\t\tlet bytes = 0;\n\n\t\t\t\tif (opts.stream) {\n\t\t\t\t\tbytes = await streamAndSave(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tvoiceId,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\tlatencyTier,\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tshouldPlay,\n\t\t\t\t\t\tspinner\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tbytes = await convertAndSave(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tvoiceId,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tshouldPlay,\n\t\t\t\t\t\tspinner\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tspinner.succeed('Done');\n\n\t\t\t\tif (opts.metrics) {\n\t\t\t\t\tconst duration = Date.now() - start;\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`metrics: chars=${text.length} bytes=${bytes} model=${opts.modelId} voice=${voiceId} stream=${opts.stream} latencyTier=${latencyTier} dur=${duration}ms`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tlog.error((err as Error).message);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n}\n\nasync function resolveVoice(\n\tclient: ElevenLabsClient,\n\tvoiceInput?: string\n): Promise<string> {\n\tif (!voiceInput) {\n\t\t// Get first available voice\n\t\tconst voices = await client.listVoices();\n\t\tif (voices.length === 0) {\n\t\t\tthrow new Error('No voices available; specify --voice or set ELEVENLABS_VOICE_ID');\n\t\t}\n\t\tlog.info(`Defaulting to voice ${voices[0].name} (${voices[0].voice_id})`);\n\t\treturn voices[0].voice_id;\n\t}\n\n\t// If it looks like an ID (UUID-like), use directly\n\tif (voiceInput.length >= 15 && /[0-9]/.test(voiceInput)) {\n\t\treturn voiceInput;\n\t}\n\n\t// Search for voice by name\n\tconst voices = await client.listVoices(voiceInput);\n\tconst voiceInputLower = voiceInput.toLowerCase();\n\n\t// Exact match\n\tconst exact = voices.find((v: Voice) => v.name.toLowerCase() === voiceInputLower);\n\tif (exact) {\n\t\tlog.info(`Using voice ${exact.name} (${exact.voice_id})`);\n\t\treturn exact.voice_id;\n\t}\n\n\t// Closest match\n\tif (voices.length > 0) {\n\t\tconst v = voices[0];\n\t\tlog.info(`Using closest voice match ${v.name} (${v.voice_id})`);\n\t\treturn v.voice_id;\n\t}\n\n\tthrow new Error(`Voice \"${voiceInput}\" not found; try 'awaz voices' or -v '?'`);\n}\n\nasync function resolveText(args: string[], inputFile?: string): Promise<string> {\n\tif (inputFile) {\n\t\tif (inputFile === '-') {\n\t\t\treturn readStdin();\n\t\t}\n\t\tconst data = fs.readFileSync(inputFile, 'utf-8');\n\t\tconst text = data.trim();\n\t\tif (!text) {\n\t\t\tthrow new Error('Input file was empty');\n\t\t}\n\t\treturn text;\n\t}\n\n\tif (args.length > 0) {\n\t\treturn args.join(' ');\n\t}\n\n\treturn readStdin();\n}\n\nfunction readStdin(): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (process.stdin.isTTY) {\n\t\t\treject(new Error('No text provided; pass text args, --input-file, or pipe input'));\n\t\t\treturn;\n\t\t}\n\n\t\tlet data = '';\n\t\tprocess.stdin.setEncoding('utf-8');\n\t\tprocess.stdin.on('data', (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on('end', () => {\n\t\t\tconst text = data.trim();\n\t\t\tif (!text) {\n\t\t\t\treject(new Error('stdin was empty'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(text);\n\t\t});\n\t\tprocess.stdin.on('error', reject);\n\t});\n}\n\nfunction buildTTSRequest(\n\t_cmd: Command,\n\topts: SpeakOptions,\n\ttext: string,\n\tspeed: number,\n\toutputFormat: string\n): TTSRequest {\n\tconst voiceSettings: VoiceSettings = {\n\t\tspeed\n\t};\n\n\t// Stability\n\tif (opts.stability !== undefined) {\n\t\tconst stability = parseFloat(String(opts.stability));\n\t\tif (stability < 0 || stability > 1) {\n\t\t\tthrow new Error('Stability must be between 0 and 1');\n\t\t}\n\t\tif (opts.modelId === 'eleven_v3') {\n\t\t\tif (![0, 0.5, 1].some((v) => Math.abs(stability - v) < 1e-9)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'For eleven_v3, stability must be one of 0.0, 0.5, 1.0 (Creative/Natural/Robust)'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tvoiceSettings.stability = stability;\n\t}\n\n\t// Similarity\n\tconst similarity = opts.similarity ?? opts.similarityBoost;\n\tif (similarity !== undefined) {\n\t\tconst simVal = parseFloat(String(similarity));\n\t\tif (simVal < 0 || simVal > 1) {\n\t\t\tthrow new Error('Similarity must be between 0 and 1');\n\t\t}\n\t\tvoiceSettings.similarity_boost = simVal;\n\t}\n\n\t// Style\n\tif (opts.style !== undefined) {\n\t\tconst styleVal = parseFloat(String(opts.style));\n\t\tif (styleVal < 0 || styleVal > 1) {\n\t\t\tthrow new Error('Style must be between 0 and 1');\n\t\t}\n\t\tvoiceSettings.style = styleVal;\n\t}\n\n\t// Speaker boost\n\tif (opts.speakerBoost && opts.noSpeakerBoost) {\n\t\tthrow new Error('Choose only one of --speaker-boost or --no-speaker-boost');\n\t}\n\tif (opts.speakerBoost) {\n\t\tvoiceSettings.use_speaker_boost = true;\n\t} else if (opts.noSpeakerBoost) {\n\t\tvoiceSettings.use_speaker_boost = false;\n\t}\n\n\tconst request: TTSRequest = {\n\t\ttext,\n\t\tmodel_id: opts.modelId,\n\t\toutput_format: outputFormat,\n\t\tvoice_settings: voiceSettings\n\t};\n\n\t// Seed\n\tif (opts.seed !== undefined) {\n\t\tconst seedVal = parseInt(String(opts.seed), 10);\n\t\tif (seedVal < 0 || seedVal > 4294967295) {\n\t\t\tthrow new Error('Seed must be between 0 and 4294967295');\n\t\t}\n\t\trequest.seed = seedVal;\n\t}\n\n\t// Normalize\n\tif (opts.normalize) {\n\t\tconst norm = opts.normalize.toLowerCase().trim();\n\t\tif (!['auto', 'on', 'off'].includes(norm)) {\n\t\t\tthrow new Error('Normalize must be one of: auto, on, off');\n\t\t}\n\t\trequest.apply_text_normalization = norm;\n\t}\n\n\t// Language\n\tif (opts.lang) {\n\t\tconst lang = opts.lang.toLowerCase().trim();\n\t\tif (lang.length !== 2 || !/^[a-z]+$/.test(lang)) {\n\t\t\tthrow new Error('Lang must be a 2-letter ISO 639-1 code (e.g. en, de, fr)');\n\t\t}\n\t\trequest.language_code = lang;\n\t}\n\n\treturn request;\n}\n\nasync function streamAndSave(\n\tclient: ElevenLabsClient,\n\tvoiceId: string,\n\tpayload: TTSRequest,\n\tlatencyTier: number,\n\toutputPath: string | undefined,\n\tshouldPlay: boolean,\n\tspinner: ReturnType<typeof ora>\n): Promise<number> {\n\tconst stream = await client.streamTTS(voiceId, payload, latencyTier);\n\n\tif (!stream) {\n\t\tthrow new Error('No stream returned from API');\n\t}\n\n\tconst chunks: Uint8Array[] = [];\n\tconst reader = stream.getReader();\n\n\tlet totalBytes = 0;\n\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tif (value) {\n\t\t\tchunks.push(value);\n\t\t\ttotalBytes += value.length;\n\t\t\tspinner.text = `Generating speech... ${Math.round(totalBytes / 1024)}KB`;\n\t\t}\n\t}\n\n\tconst audioData = Buffer.concat(chunks);\n\n\t// Save to file if requested\n\tif (outputPath) {\n\t\tconst dir = path.dirname(outputPath);\n\t\tif (dir && dir !== '.') {\n\t\t\tfs.mkdirSync(dir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(outputPath, audioData);\n\t\tlog.info(`Audio saved to ${outputPath}`);\n\t}\n\n\t// Play audio\n\tif (shouldPlay) {\n\t\tawait playAudio(audioData, spinner);\n\t}\n\n\treturn totalBytes;\n}\n\nasync function playAudio(audioData: Buffer, spinner: ReturnType<typeof ora>): Promise<void> {\n\tconst platform = os.platform();\n\t\n\t// Write to temp file\n\tconst tmpFile = path.join(os.tmpdir(), `awaz-${Date.now()}.mp3`);\n\tfs.writeFileSync(tmpFile, audioData);\n\n\treturn new Promise((resolve, reject) => {\n\t\tlet player: ReturnType<typeof spawn>;\n\n\t\tif (platform === 'darwin') {\n\t\t\tplayer = spawn('afplay', [tmpFile]);\n\t\t} else if (platform === 'linux') {\n\t\t\tplayer = spawn('aplay', [tmpFile]);\n\t\t} else if (platform === 'win32') {\n\t\t\tplayer = spawn('powershell', ['-c', `(New-Object Media.SoundPlayer '${tmpFile}').PlaySync()`]);\n\t\t} else {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\treject(new Error(`Unsupported platform: ${platform}`));\n\t\t\treturn;\n\t\t}\n\n\t\tspinner.text = 'Playing audio...';\n\n\t\tplayer.on('close', (code) => {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(new Error(`Audio player exited with code ${code}`));\n\t\t\t}\n\t\t});\n\n\t\tplayer.on('error', (err) => {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\treject(err);\n\t\t});\n\t});\n}\n\nasync function convertAndSave(\n\tclient: ElevenLabsClient,\n\tvoiceId: string,\n\tpayload: TTSRequest,\n\toutputPath: string | undefined,\n\tshouldPlay: boolean,\n\tspinner: ReturnType<typeof ora>\n): Promise<number> {\n\tspinner.text = 'Converting text to speech...';\n\tconst audioData = await client.convertTTS(voiceId, payload);\n\n\t// Save to file if requested\n\tif (outputPath) {\n\t\tconst dir = path.dirname(outputPath);\n\t\tif (dir && dir !== '.') {\n\t\t\tfs.mkdirSync(dir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(outputPath, audioData);\n\t\tlog.info(`Audio saved to ${outputPath}`);\n\t}\n\n\t// Play audio\n\tif (shouldPlay) {\n\t\tawait playAudio(audioData, spinner);\n\t}\n\n\treturn audioData.length;\n}\n\nfunction inferFormatFromExt(filePath: string): string | null {\n\tconst ext = path.extname(filePath).toLowerCase();\n\tswitch (ext) {\n\t\tcase '.mp3':\n\t\t\treturn 'mp3_44100_128';\n\t\tcase '.wav':\n\t\tcase '.wave':\n\t\t\treturn 'pcm_44100';\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n\n","/**\n * ElevenLabs API client for text-to-speech\n */\n\nexport interface Voice {\n\tvoice_id: string;\n\tname: string;\n\tcategory: string;\n\tlabels?: Record<string, string>;\n\tpreview_url?: string;\n}\n\nexport interface VoiceSettings {\n\tstability?: number;\n\tsimilarity_boost?: number;\n\tstyle?: number;\n\tuse_speaker_boost?: boolean;\n\tspeed?: number;\n}\n\nexport interface TTSRequest {\n\ttext: string;\n\tmodel_id?: string;\n\tvoice_settings?: VoiceSettings;\n\toutput_format?: string;\n\tseed?: number;\n\tapply_text_normalization?: string;\n\tlanguage_code?: string;\n}\n\ninterface ListVoicesResponse {\n\tvoices: Voice[];\n\tnext_page_token?: string;\n}\n\nexport interface ElevenLabsClientConfig {\n\tapiKey: string;\n\tbaseUrl?: string;\n}\n\nexport class ElevenLabsClient {\n\tprivate readonly baseUrl: string;\n\tprivate readonly apiKey: string;\n\n\tconstructor(config: ElevenLabsClientConfig) {\n\t\tthis.apiKey = config.apiKey;\n\t\tthis.baseUrl = config.baseUrl || 'https://api.elevenlabs.io';\n\t}\n\n\tprivate async request<T>(\n\t\tpath: string,\n\t\toptions: RequestInit = {}\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst headers: Record<string, string> = {\n\t\t\t'xi-api-key': this.apiKey,\n\t\t\tAccept: 'application/json',\n\t\t\t...(options.headers as Record<string, string>)\n\t\t};\n\n\t\tconst response = await fetch(url, {\n\t\t\t...options,\n\t\t\theaders\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`ElevenLabs API error: ${response.status} ${response.statusText}: ${text}`);\n\t\t}\n\n\t\treturn response.json() as Promise<T>;\n\t}\n\n\t/**\n\t * List available voices\n\t */\n\tasync listVoices(search?: string): Promise<Voice[]> {\n\t\tlet path = '/v1/voices';\n\t\tif (search) {\n\t\t\tpath += `?search=${encodeURIComponent(search)}`;\n\t\t}\n\n\t\tconst response = await this.request<ListVoicesResponse>(path);\n\t\treturn response.voices;\n\t}\n\n\t/**\n\t * Stream TTS audio\n\t */\n\tasync streamTTS(\n\t\tvoiceId: string,\n\t\tpayload: TTSRequest,\n\t\tlatencyTier = 0\n\t): Promise<ReadableStream<Uint8Array> | null> {\n\t\tlet path = `/v1/text-to-speech/${voiceId}/stream`;\n\t\tif (latencyTier > 0) {\n\t\t\tpath += `?optimize_streaming_latency=${latencyTier}`;\n\t\t}\n\n\t\tconst response = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\tAccept: 'audio/mpeg',\n\t\t\t\t'xi-api-key': this.apiKey\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`Stream TTS failed: ${response.status}: ${text}`);\n\t\t}\n\n\t\treturn response.body;\n\t}\n\n\t/**\n\t * Convert text to speech (non-streaming)\n\t */\n\tasync convertTTS(voiceId: string, payload: TTSRequest): Promise<Buffer> {\n\t\tconst path = `/v1/text-to-speech/${voiceId}`;\n\n\t\tconst response = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\tAccept: 'audio/mpeg',\n\t\t\t\t'xi-api-key': this.apiKey\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`Convert TTS failed: ${response.status}: ${text}`);\n\t\t}\n\n\t\tconst arrayBuffer = await response.arrayBuffer();\n\t\treturn Buffer.from(arrayBuffer);\n\t}\n}\n\n/**\n * Get API key from environment or throw\n */\nexport function getApiKey(providedKey?: string): string {\n\tconst key =\n\t\tprovidedKey ||\n\t\tprocess.env.ELEVENLABS_API_KEY ||\n\t\tprocess.env.AWAZ_API_KEY;\n\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t'Missing ElevenLabs API key. Set --api-key or ELEVENLABS_API_KEY environment variable.'\n\t\t);\n\t}\n\n\treturn key;\n}\n\n/**\n * Get default voice ID from environment\n */\nexport function getDefaultVoiceId(): string | undefined {\n\treturn process.env.ELEVENLABS_VOICE_ID || process.env.AWAZ_VOICE_ID;\n}\n","import pc from 'picocolors';\n\nexport const banner = `\n${pc.white('▄▀█ █░█░█ ▄▀█ ▀█')}\n${pc.gray('█▀█ ▀▄▀▄▀ █▀█ █▄')}\n${pc.dim('text to speech cli.')}\n`;\n\nexport function showBanner(): void {\n\tconsole.log(banner);\n}\n","import pc from 'picocolors';\n\nexport function error(msg: string): void {\n\tconsole.error(`${pc.red('✖')} ${msg}`);\n}\n\nexport function warn(msg: string): void {\n\tconsole.error(`${pc.yellow('⚠')} ${msg}`);\n}\n\nexport function info(msg: string): void {\n\tconsole.error(`${pc.blue('ℹ')} ${msg}`);\n}\n\nexport function success(msg: string): void {\n\tconsole.error(`${pc.green('✔')} ${msg}`);\n}\n\nexport function dim(msg: string): string {\n\treturn pc.dim(msg);\n}\n\nexport function bold(msg: string): string {\n\treturn pc.bold(msg);\n}\n\nexport function cyan(msg: string): string {\n\treturn pc.cyan(msg);\n}\n\nexport function yellow(msg: string): string {\n\treturn pc.yellow(msg);\n}\n\nexport function green(msg: string): string {\n\treturn pc.green(msg);\n}\n\nexport function red(msg: string): string {\n\treturn pc.red(msg);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\ninterface PackageJson {\n\tname: string;\n\tversion: string;\n\tdescription: string;\n}\n\nlet _packageJson: PackageJson | null = null;\n\nexport function getPackageJson(): PackageJson {\n\tif (_packageJson) {\n\t\treturn _packageJson;\n\t}\n\n\t// Try to find package.json, walking up from current file\n\tlet dir = __dirname;\n\tfor (let i = 0; i < 5; i++) {\n\t\tconst pkgPath = path.join(dir, 'package.json');\n\t\tif (fs.existsSync(pkgPath)) {\n\t\t\t_packageJson = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as PackageJson;\n\t\t\treturn _packageJson;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n\n\t// Fallback\n\treturn {\n\t\tname: 'awaz',\n\t\tversion: '0.0.1',\n\t\tdescription: 'Text to speech. Done right.'\n\t};\n}\n\nexport function getVersion(): string {\n\treturn getPackageJson().version;\n}\n","export function padRight(str: string, len: number): string {\n\tif (str.length >= len) return str.slice(0, len);\n\treturn str + ' '.repeat(len - str.length);\n}\n","import { Command } from 'commander';\nimport ora from 'ora';\nimport { ElevenLabsClient, getApiKey } from '../lib/elevenlabs.js';\nimport { log, padRight } from '../utils/index.js';\n\ninterface VoicesOptions {\n\tsearch?: string;\n\tlimit: number;\n\tapiKey?: string;\n\tbaseUrl: string;\n}\n\nexport function createVoicesCommand(): Command {\n\treturn new Command('voices')\n\t\t.description('List voices')\n\t\t.option('--search <query>', 'Filter by name')\n\t\t.option('--limit <n>', 'Max results (0 = all)', '100')\n\t\t.action(async function (this: Command) {\n\t\t\tconst opts = this.optsWithGlobals<VoicesOptions>();\n\t\t\tconst limit = parseInt(String(opts.limit), 10);\n\n\t\t\tconst spinner = ora('Fetching voices...').start();\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = getApiKey(opts.apiKey);\n\t\t\t\tconst client = new ElevenLabsClient({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tbaseUrl: opts.baseUrl\n\t\t\t\t});\n\n\t\t\t\tlet voices = await client.listVoices(opts.search);\n\t\t\t\tspinner.stop();\n\n\t\t\t\tif (limit > 0 && voices.length > limit) {\n\t\t\t\t\tvoices = voices.slice(0, limit);\n\t\t\t\t}\n\n\t\t\t\t// Print header\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${padRight('VOICE ID', 24)} ${padRight('NAME', 24)} CATEGORY`\n\t\t\t\t);\n\n\t\t\t\t// Print rows\n\t\t\t\tfor (const v of voices) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${padRight(v.voice_id, 24)} ${padRight(v.name, 24)} ${v.category}`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (voices.length === 0) {\n\t\t\t\t\tlog.info('No voices found');\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tspinner.fail('Failed to fetch voices');\n\t\t\t\tlog.error((err as Error).message);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n}\n\n\n","import { Command } from 'commander';\nimport { promptingGuide } from './prompting-guide.js';\n\nexport function createPromptingCommand(): Command {\n\treturn new Command('prompting')\n\t\t.aliases(['prompt', 'guide', 'tips'])\n\t\t.description('Tips for better output')\n\t\t.action(() => {\n\t\t\tconsole.log(promptingGuide.trim());\n\t\t});\n}\n","export const promptingGuide = `# Better results from awaz\n\nWhat you write matters. Here's what works.\n\n## Models\n\n**v3 (default)** — Most expressive. Tags like [whispers], [laughs]. No SSML.\n**v2** — Reliable. SSML pauses work. Predictable.\n**Flash** — Fast. ~75ms. Half the cost.\n**Turbo** — Balanced. ~250ms. Good quality.\n\n## Writing tips\n\nWrite how you'd say it. Short sentences. Natural breaks.\n\n**Punctuation = pacing:**\n- Comma, dash → slight pause\n- Ellipsis... → dramatic pause\n- Period → full stop\n- ! → energy\n\n**Spell it how it sounds.** \"API\" wrong? Try \"A P I\" or \"ay-pee-eye\".\n\n## v3 tags\n\n**Emotions:** [whispers], [shouts], [laughs], [sighs], [sarcastic], [excited]\n**Actions:** [clears throat], [exhales], [swallows]\n**Effects:** [applause], [short pause], [long pause]\n**Experimental:** [strong French accent], [sings]\n\nNot every voice responds to every tag. Experiment.\n\n## The knobs\n\n**--stability** (0-1)\nHigher = consistent. Lower = varied. v3 uses presets: 0=Creative, 0.5=Natural, 1=Robust.\n\n**--similarity** (0-1)\nHigher = closer to original voice sample.\n\n**--style** (0-1)\nHigher = more expressive. Can get weird if too high.\n\n**--speaker-boost**\nAdds clarity. Sometimes helps.\n\n**--seed**\nSame seed = same output. Good for A/B testing.\n\n## Examples\n\nNatural:\n awaz -v Roger --stability 0.5 \"We shipped today. It worked.\"\n\nFast:\n awaz --model-id eleven_flash_v2_5 \"Quick and cheap.\"\n\nDramatic (v3):\n awaz \"[whispers] Don't move. [short pause] Something's there...\"\n\n## TL;DR\n\n1. v3 for expression, v2 for reliability, Flash for speed\n2. Write naturally\n3. Experiment with tags on v3\n4. Tweak stability/similarity if it sounds off\n`;\n"],"mappings":"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","names":["Command","fs","path","config","path","pc","__dirname","voices","fs","resolve","path","Command","ora","Command","ora","Command","Command","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/speak.ts","../src/lib/elevenlabs.ts","../src/utils/banner.ts","../src/utils/log.ts","../src/utils/package.ts","../src/utils/helpers.ts","../src/commands/voices.ts","../src/commands/prompting.ts","../src/commands/prompting-guide.ts"],"sourcesContent":["import { Command, Option } from 'commander';\nimport { config } from 'dotenv';\nimport { resolve } from 'node:path';\nimport { createPromptingCommand, createSpeakCommand, createVoicesCommand } from './commands/index.js';\nimport { banner, getVersion } from './utils/index.js';\n\nconst program = new Command();\n\n// Get version from package.json\nconst version = getVersion();\n\nprogram\n\t.name('awaz')\n\t.description('Text to speech. Done right.')\n\t.version(version, '-v, --version', 'Print version and exit')\n\t.helpOption('-h, --help', 'Display help for command')\n\t.addOption(\n\t\tnew Option('--api-key <key>', 'ElevenLabs API key (or ELEVENLABS_API_KEY)')\n\t)\n\t.addOption(\n\t\tnew Option('--base-url <url>', 'Override ElevenLabs API base URL')\n\t\t\t.default('https://api.elevenlabs.io')\n\t)\n\t.addOption(new Option('--local').hideHelp())\n\t.addOption(new Option('--env <path>', 'Load env file from path'));\n\n// Add commands\nprogram.addCommand(createSpeakCommand());\nprogram.addCommand(createVoicesCommand());\nprogram.addCommand(createPromptingCommand());\n\n// Check if called like `awaz \"Hello\"` (default to speak subcommand)\nfunction maybeDefaultToSpeak(): void {\n\tif (process.argv.length <= 2) {\n\t\treturn;\n\t}\n\n\t// npm/pnpm pass-through typically prefixes args with \"--\"; drop it\n\tif (process.argv[2] === '--') {\n\t\tprocess.argv = [process.argv[0], process.argv[1], ...process.argv.slice(3)];\n\t\tif (process.argv.length <= 2) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconst first = process.argv[2];\n\n\t// Check for known subcommands\n\tconst knownCommands = ['speak', 'voices', 'prompting', 'prompt', 'guide', 'tips'];\n\tconst isKnown =\n\t\tknownCommands.includes(first.toLowerCase()) ||\n\t\tfirst === '-h' ||\n\t\tfirst === '--help' ||\n\t\tfirst === '-v' ||\n\t\tfirst === '--version';\n\n\tif (!isKnown) {\n\t\t// Insert 'speak' subcommand\n\t\tprocess.argv = [process.argv[0], process.argv[1], 'speak', ...process.argv.slice(2)];\n\t}\n}\n\n// Override version output to be clean (no banner)\nprogram.configureOutput({\n\twriteOut: (str) => process.stdout.write(str),\n\twriteErr: (str) => process.stderr.write(str)\n});\n\n// Custom help to show banner\nconst originalHelp = program.helpInformation.bind(program);\nprogram.helpInformation = function (): string {\n\treturn banner + '\\n' + originalHelp();\n};\n\nexport async function run(): Promise<void> {\n\t// Check for version flag early\n\tif (process.argv.includes('-v') || process.argv.includes('--version')) {\n\t\tconsole.log(version);\n\t\tprocess.exit(0);\n\t}\n\n\t// Load .env file: explicit path > local .env > env var\n\tconst envIndex = process.argv.findIndex(arg => arg === '--env');\n\tconst hasEnvFlag = envIndex !== -1 && process.argv[envIndex + 1];\n\tconst hasEnvKey = process.env.ELEVENLABS_API_KEY || process.env.AWAZ_API_KEY;\n\n\tif (hasEnvFlag) {\n\t\tconfig({ path: resolve(process.argv[envIndex + 1]), quiet: true });\n\t}\n\n\tif (!hasEnvFlag && !hasEnvKey) {\n\t\tconfig({ quiet: true });\n\t}\n\n\tmaybeDefaultToSpeak();\n\tawait program.parseAsync(process.argv);\n}\n\nexport { program };\n\n// Run the CLI\nrun().catch((err) => {\n\tconsole.error(err);\n\tprocess.exit(1);\n});\n","import { Command } from 'commander';\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport ora from 'ora';\nimport {\n\tElevenLabsClient,\n\tgetApiKey,\n\tgetDefaultVoiceId,\n\ttype TTSRequest,\n\ttype Voice,\n\ttype VoiceSettings\n} from '../lib/elevenlabs.js';\nimport { log, padRight } from '../utils/index.js';\n\ninterface SpeakOptions {\n\tvoice?: string;\n\tvoiceId?: string;\n\tmodelId: string;\n\toutput?: string;\n\tformat: string;\n\tstream: boolean;\n\tplay: boolean;\n\tlatencyTier: number;\n\tspeed: number;\n\trate?: number;\n\tinputFile?: string;\n\tstability?: number;\n\tsimilarity?: number;\n\tsimilarityBoost?: number;\n\tstyle?: number;\n\tspeakerBoost?: boolean;\n\tnoSpeakerBoost?: boolean;\n\tseed?: number;\n\tnormalize?: string;\n\tlang?: string;\n\tmetrics: boolean;\n\tapiKey?: string;\n\tbaseUrl: string;\n}\n\nconst DEFAULT_WPM = 175;\n\nexport function createSpeakCommand(): Command {\n\treturn new Command('speak')\n\t\t.description('Speak text (streams by default)')\n\t\t.argument('[text...]', 'Text to speak')\n\t\t.option('--voice-id <id>', 'Voice ID')\n\t\t.option('-v, --voice <name>', 'Voice name or ID (use \"?\" to list)')\n\t\t.option('--model-id <id>', 'ElevenLabs model (eleven_v3, eleven_multilingual_v2, etc.)', 'eleven_v3')\n\t\t.option('-o, --output <path>', 'Save audio to file')\n\t\t.option('--format <format>', 'Audio format', 'mp3_44100_128')\n\t\t.option('--stream', 'Stream audio while generating', true)\n\t\t.option('--no-stream', 'Disable streaming')\n\t\t.option('--play', 'Play audio through speakers', true)\n\t\t.option('--no-play', 'Disable playback')\n\t\t.option('--latency-tier <n>', 'Lower = faster (0-4)', '0')\n\t\t.option('--speed <n>', 'Speed multiplier (0.5-2.0)', '1.0')\n\t\t.option('-r, --rate <wpm>', 'Words per minute (default 175)')\n\t\t.option('-f, --input-file <path>', 'Read from file (use \"-\" for stdin)')\n\t\t.option('--stability <n>', 'Voice consistency (0-1)')\n\t\t.option('--similarity <n>', 'Match to original voice (0-1)')\n\t\t.option('--similarity-boost <n>', 'Same as --similarity')\n\t\t.option('--style <n>', 'Expressiveness (0-1)')\n\t\t.option('--speaker-boost', 'Add clarity')\n\t\t.option('--no-speaker-boost', 'No clarity boost')\n\t\t.option('--seed <n>', 'For reproducible output')\n\t\t.option('--normalize <mode>', 'Handle numbers/URLs: auto|on|off')\n\t\t.option('--lang <code>', 'Language (en, de, fr, etc.)')\n\t\t.option('--metrics', 'Show timing stats', false)\n\t\t// macOS say compatibility flags (no-op)\n\t\t.option('--progress', 'macOS say compatibility (no-op)')\n\t\t.option('--network-send <host>', 'macOS say compatibility (no-op)')\n\t\t.option('--audio-device <device>', 'macOS say compatibility (no-op)')\n\t\t.option('--interactive <mode>', 'macOS say compatibility (no-op)')\n\t\t.option('--file-format <fmt>', 'macOS say compatibility (no-op)')\n\t\t.option('--data-format <fmt>', 'macOS say compatibility (no-op)')\n\t\t.option('--channels <n>', 'macOS say compatibility (no-op)')\n\t\t.option('--bit-rate <n>', 'macOS say compatibility (no-op)')\n\t\t.option('--quality <n>', 'macOS say compatibility (no-op)')\n\t\t.action(async function (this: Command, textArgs: string[]) {\n\t\t\tconst opts = this.optsWithGlobals<SpeakOptions>();\n\n\t\t\ttry {\n\t\t\t\t// Parse numeric options\n\t\t\t\tconst speed = parseFloat(String(opts.speed));\n\t\t\t\tconst latencyTier = parseInt(String(opts.latencyTier), 10);\n\n\t\t\t\t// Validate speed\n\t\t\t\tlet finalSpeed = speed;\n\t\t\t\tif (opts.rate) {\n\t\t\t\t\tconst rate = parseInt(String(opts.rate), 10);\n\t\t\t\t\tfinalSpeed = rate / DEFAULT_WPM;\n\t\t\t\t\tif (finalSpeed <= 0.5 || finalSpeed >= 2.0) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Rate ${rate} wpm maps to speed ${finalSpeed.toFixed(2)}, which is outside the allowed 0.5–2.0 range`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else if (finalSpeed <= 0.5 || finalSpeed >= 2.0) {\n\t\t\t\t\tthrow new Error('Speed must be between 0.5 and 2.0 (e.g. 1.1 for 10% faster)');\n\t\t\t\t}\n\n\t\t\t\t// Get API key and create client\n\t\t\t\tconst apiKey = getApiKey(opts.apiKey);\n\t\t\t\tconst client = new ElevenLabsClient({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tbaseUrl: opts.baseUrl\n\t\t\t\t});\n\n\t\t\t\t// Resolve voice\n\t\t\t\tlet voiceId = opts.voice || opts.voiceId || getDefaultVoiceId();\n\n\t\t\t\tif (voiceId === '?') {\n\t\t\t\t\t// List voices and exit\n\t\t\t\t\tconst voices = await client.listVoices();\n\t\t\t\t\tconsole.log(`${padRight('VOICE ID', 24)} ${padRight('NAME', 24)} CATEGORY`);\n\t\t\t\t\tfor (const v of voices) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`${padRight(v.voice_id, 24)} ${padRight(v.name, 24)} ${v.category}`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvoiceId = await resolveVoice(client, voiceId);\n\n\t\t\t\t// Resolve text\n\t\t\t\tconst text = await resolveText(textArgs, opts.inputFile);\n\n\t\t\t\t// Determine if we should play (disable if output is set and play wasn't explicitly set)\n\t\t\t\tlet shouldPlay = opts.play;\n\t\t\t\tif (opts.output && !this.getOptionValueSource('play')) {\n\t\t\t\t\tshouldPlay = false;\n\t\t\t\t}\n\n\t\t\t\t// Infer format from output extension\n\t\t\t\tlet outputFormat = opts.format;\n\t\t\t\tif (opts.output) {\n\t\t\t\t\tconst inferred = inferFormatFromExt(opts.output);\n\t\t\t\t\tif (inferred) {\n\t\t\t\t\t\toutputFormat = inferred;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Build TTS request\n\t\t\t\tconst payload = buildTTSRequest(this, opts, text, finalSpeed, outputFormat);\n\n\t\t\t\tconst spinner = ora('Generating speech...').start();\n\t\t\t\tconst start = Date.now();\n\t\t\t\tlet bytes = 0;\n\n\t\t\t\tif (opts.stream) {\n\t\t\t\t\tbytes = await streamAndSave(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tvoiceId,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\tlatencyTier,\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tshouldPlay,\n\t\t\t\t\t\tspinner\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tbytes = await convertAndSave(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tvoiceId,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tshouldPlay,\n\t\t\t\t\t\tspinner\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tspinner.succeed('Done');\n\n\t\t\t\tif (opts.metrics) {\n\t\t\t\t\tconst duration = Date.now() - start;\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`metrics: chars=${text.length} bytes=${bytes} model=${opts.modelId} voice=${voiceId} stream=${opts.stream} latencyTier=${latencyTier} dur=${duration}ms`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tlog.error((err as Error).message);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n}\n\nasync function resolveVoice(\n\tclient: ElevenLabsClient,\n\tvoiceInput?: string\n): Promise<string> {\n\tif (!voiceInput) {\n\t\t// Get first available voice\n\t\tconst voices = await client.listVoices();\n\t\tif (voices.length === 0) {\n\t\t\tthrow new Error('No voices available; specify --voice or set ELEVENLABS_VOICE_ID');\n\t\t}\n\t\tlog.info(`Defaulting to voice ${voices[0].name} (${voices[0].voice_id})`);\n\t\treturn voices[0].voice_id;\n\t}\n\n\t// If it looks like an ID (UUID-like), use directly\n\tif (voiceInput.length >= 15 && /[0-9]/.test(voiceInput)) {\n\t\treturn voiceInput;\n\t}\n\n\t// Search for voice by name\n\tconst voices = await client.listVoices(voiceInput);\n\tconst voiceInputLower = voiceInput.toLowerCase();\n\n\t// Exact match\n\tconst exact = voices.find((v: Voice) => v.name.toLowerCase() === voiceInputLower);\n\tif (exact) {\n\t\tlog.info(`Using voice ${exact.name} (${exact.voice_id})`);\n\t\treturn exact.voice_id;\n\t}\n\n\t// Closest match\n\tif (voices.length > 0) {\n\t\tconst v = voices[0];\n\t\tlog.info(`Using closest voice match ${v.name} (${v.voice_id})`);\n\t\treturn v.voice_id;\n\t}\n\n\tthrow new Error(`Voice \"${voiceInput}\" not found; try 'awaz voices' or -v '?'`);\n}\n\nasync function resolveText(args: string[], inputFile?: string): Promise<string> {\n\tif (inputFile) {\n\t\tif (inputFile === '-') {\n\t\t\treturn readStdin();\n\t\t}\n\t\tconst data = fs.readFileSync(inputFile, 'utf-8');\n\t\tconst text = data.trim();\n\t\tif (!text) {\n\t\t\tthrow new Error('Input file was empty');\n\t\t}\n\t\treturn text;\n\t}\n\n\tif (args.length > 0) {\n\t\treturn args.join(' ');\n\t}\n\n\treturn readStdin();\n}\n\nfunction readStdin(): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (process.stdin.isTTY) {\n\t\t\treject(new Error('No text provided; pass text args, --input-file, or pipe input'));\n\t\t\treturn;\n\t\t}\n\n\t\tlet data = '';\n\t\tprocess.stdin.setEncoding('utf-8');\n\t\tprocess.stdin.on('data', (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on('end', () => {\n\t\t\tconst text = data.trim();\n\t\t\tif (!text) {\n\t\t\t\treject(new Error('stdin was empty'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(text);\n\t\t});\n\t\tprocess.stdin.on('error', reject);\n\t});\n}\n\nfunction buildTTSRequest(\n\t_cmd: Command,\n\topts: SpeakOptions,\n\ttext: string,\n\tspeed: number,\n\toutputFormat: string\n): TTSRequest {\n\tconst voiceSettings: VoiceSettings = {\n\t\tspeed\n\t};\n\n\t// Stability\n\tif (opts.stability !== undefined) {\n\t\tconst stability = parseFloat(String(opts.stability));\n\t\tif (stability < 0 || stability > 1) {\n\t\t\tthrow new Error('Stability must be between 0 and 1');\n\t\t}\n\t\tif (opts.modelId === 'eleven_v3') {\n\t\t\tif (![0, 0.5, 1].some((v) => Math.abs(stability - v) < 1e-9)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'For eleven_v3, stability must be one of 0.0, 0.5, 1.0 (Creative/Natural/Robust)'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tvoiceSettings.stability = stability;\n\t}\n\n\t// Similarity\n\tconst similarity = opts.similarity ?? opts.similarityBoost;\n\tif (similarity !== undefined) {\n\t\tconst simVal = parseFloat(String(similarity));\n\t\tif (simVal < 0 || simVal > 1) {\n\t\t\tthrow new Error('Similarity must be between 0 and 1');\n\t\t}\n\t\tvoiceSettings.similarity_boost = simVal;\n\t}\n\n\t// Style\n\tif (opts.style !== undefined) {\n\t\tconst styleVal = parseFloat(String(opts.style));\n\t\tif (styleVal < 0 || styleVal > 1) {\n\t\t\tthrow new Error('Style must be between 0 and 1');\n\t\t}\n\t\tvoiceSettings.style = styleVal;\n\t}\n\n\t// Speaker boost\n\tif (opts.speakerBoost && opts.noSpeakerBoost) {\n\t\tthrow new Error('Choose only one of --speaker-boost or --no-speaker-boost');\n\t}\n\tif (opts.speakerBoost) {\n\t\tvoiceSettings.use_speaker_boost = true;\n\t} else if (opts.noSpeakerBoost) {\n\t\tvoiceSettings.use_speaker_boost = false;\n\t}\n\n\tconst request: TTSRequest = {\n\t\ttext,\n\t\tmodel_id: opts.modelId,\n\t\toutput_format: outputFormat,\n\t\tvoice_settings: voiceSettings\n\t};\n\n\t// Seed\n\tif (opts.seed !== undefined) {\n\t\tconst seedVal = parseInt(String(opts.seed), 10);\n\t\tif (seedVal < 0 || seedVal > 4294967295) {\n\t\t\tthrow new Error('Seed must be between 0 and 4294967295');\n\t\t}\n\t\trequest.seed = seedVal;\n\t}\n\n\t// Normalize\n\tif (opts.normalize) {\n\t\tconst norm = opts.normalize.toLowerCase().trim();\n\t\tif (!['auto', 'on', 'off'].includes(norm)) {\n\t\t\tthrow new Error('Normalize must be one of: auto, on, off');\n\t\t}\n\t\trequest.apply_text_normalization = norm;\n\t}\n\n\t// Language\n\tif (opts.lang) {\n\t\tconst lang = opts.lang.toLowerCase().trim();\n\t\tif (lang.length !== 2 || !/^[a-z]+$/.test(lang)) {\n\t\t\tthrow new Error('Lang must be a 2-letter ISO 639-1 code (e.g. en, de, fr)');\n\t\t}\n\t\trequest.language_code = lang;\n\t}\n\n\treturn request;\n}\n\nasync function streamAndSave(\n\tclient: ElevenLabsClient,\n\tvoiceId: string,\n\tpayload: TTSRequest,\n\tlatencyTier: number,\n\toutputPath: string | undefined,\n\tshouldPlay: boolean,\n\tspinner: ReturnType<typeof ora>\n): Promise<number> {\n\tconst stream = await client.streamTTS(voiceId, payload, latencyTier);\n\n\tif (!stream) {\n\t\tthrow new Error('No stream returned from API');\n\t}\n\n\tconst chunks: Uint8Array[] = [];\n\tconst reader = stream.getReader();\n\n\tlet totalBytes = 0;\n\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tif (value) {\n\t\t\tchunks.push(value);\n\t\t\ttotalBytes += value.length;\n\t\t\tspinner.text = `Generating speech... ${Math.round(totalBytes / 1024)}KB`;\n\t\t}\n\t}\n\n\tconst audioData = Buffer.concat(chunks);\n\n\t// Save to file if requested\n\tif (outputPath) {\n\t\tconst dir = path.dirname(outputPath);\n\t\tif (dir && dir !== '.') {\n\t\t\tfs.mkdirSync(dir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(outputPath, audioData);\n\t\tlog.info(`Audio saved to ${outputPath}`);\n\t}\n\n\t// Play audio\n\tif (shouldPlay) {\n\t\tawait playAudio(audioData, spinner);\n\t}\n\n\treturn totalBytes;\n}\n\nasync function playAudio(audioData: Buffer, spinner: ReturnType<typeof ora>): Promise<void> {\n\tconst platform = os.platform();\n\t\n\t// Write to temp file\n\tconst tmpFile = path.join(os.tmpdir(), `awaz-${Date.now()}.mp3`);\n\tfs.writeFileSync(tmpFile, audioData);\n\n\treturn new Promise((resolve, reject) => {\n\t\tlet player: ReturnType<typeof spawn>;\n\n\t\tif (platform === 'darwin') {\n\t\t\tplayer = spawn('afplay', [tmpFile]);\n\t\t} else if (platform === 'linux') {\n\t\t\tplayer = spawn('aplay', [tmpFile]);\n\t\t} else if (platform === 'win32') {\n\t\t\tplayer = spawn('powershell', ['-c', `(New-Object Media.SoundPlayer '${tmpFile}').PlaySync()`]);\n\t\t} else {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\treject(new Error(`Unsupported platform: ${platform}`));\n\t\t\treturn;\n\t\t}\n\n\t\tspinner.text = 'Playing audio...';\n\n\t\tplayer.on('close', (code) => {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(new Error(`Audio player exited with code ${code}`));\n\t\t\t}\n\t\t});\n\n\t\tplayer.on('error', (err) => {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t\treject(err);\n\t\t});\n\t});\n}\n\nasync function convertAndSave(\n\tclient: ElevenLabsClient,\n\tvoiceId: string,\n\tpayload: TTSRequest,\n\toutputPath: string | undefined,\n\tshouldPlay: boolean,\n\tspinner: ReturnType<typeof ora>\n): Promise<number> {\n\tspinner.text = 'Converting text to speech...';\n\tconst audioData = await client.convertTTS(voiceId, payload);\n\n\t// Save to file if requested\n\tif (outputPath) {\n\t\tconst dir = path.dirname(outputPath);\n\t\tif (dir && dir !== '.') {\n\t\t\tfs.mkdirSync(dir, { recursive: true });\n\t\t}\n\t\tfs.writeFileSync(outputPath, audioData);\n\t\tlog.info(`Audio saved to ${outputPath}`);\n\t}\n\n\t// Play audio\n\tif (shouldPlay) {\n\t\tawait playAudio(audioData, spinner);\n\t}\n\n\treturn audioData.length;\n}\n\nfunction inferFormatFromExt(filePath: string): string | null {\n\tconst ext = path.extname(filePath).toLowerCase();\n\tswitch (ext) {\n\t\tcase '.mp3':\n\t\t\treturn 'mp3_44100_128';\n\t\tcase '.wav':\n\t\tcase '.wave':\n\t\t\treturn 'pcm_44100';\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n\n","/**\n * ElevenLabs API client for text-to-speech\n */\n\nexport interface Voice {\n\tvoice_id: string;\n\tname: string;\n\tcategory: string;\n\tlabels?: Record<string, string>;\n\tpreview_url?: string;\n}\n\nexport interface VoiceSettings {\n\tstability?: number;\n\tsimilarity_boost?: number;\n\tstyle?: number;\n\tuse_speaker_boost?: boolean;\n\tspeed?: number;\n}\n\nexport interface TTSRequest {\n\ttext: string;\n\tmodel_id?: string;\n\tvoice_settings?: VoiceSettings;\n\toutput_format?: string;\n\tseed?: number;\n\tapply_text_normalization?: string;\n\tlanguage_code?: string;\n}\n\ninterface ListVoicesResponse {\n\tvoices: Voice[];\n\tnext_page_token?: string;\n}\n\nexport interface ElevenLabsClientConfig {\n\tapiKey: string;\n\tbaseUrl?: string;\n}\n\nexport class ElevenLabsClient {\n\tprivate readonly baseUrl: string;\n\tprivate readonly apiKey: string;\n\n\tconstructor(config: ElevenLabsClientConfig) {\n\t\tthis.apiKey = config.apiKey;\n\t\tthis.baseUrl = config.baseUrl || 'https://api.elevenlabs.io';\n\t}\n\n\tprivate async request<T>(\n\t\tpath: string,\n\t\toptions: RequestInit = {}\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst headers: Record<string, string> = {\n\t\t\t'xi-api-key': this.apiKey,\n\t\t\tAccept: 'application/json',\n\t\t\t...(options.headers as Record<string, string>)\n\t\t};\n\n\t\tconst response = await fetch(url, {\n\t\t\t...options,\n\t\t\theaders\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`ElevenLabs API error: ${response.status} ${response.statusText}: ${text}`);\n\t\t}\n\n\t\treturn response.json() as Promise<T>;\n\t}\n\n\t/**\n\t * List available voices\n\t */\n\tasync listVoices(search?: string): Promise<Voice[]> {\n\t\tlet path = '/v1/voices';\n\t\tif (search) {\n\t\t\tpath += `?search=${encodeURIComponent(search)}`;\n\t\t}\n\n\t\tconst response = await this.request<ListVoicesResponse>(path);\n\t\treturn response.voices;\n\t}\n\n\t/**\n\t * Stream TTS audio\n\t */\n\tasync streamTTS(\n\t\tvoiceId: string,\n\t\tpayload: TTSRequest,\n\t\tlatencyTier = 0\n\t): Promise<ReadableStream<Uint8Array> | null> {\n\t\tlet path = `/v1/text-to-speech/${voiceId}/stream`;\n\t\tif (latencyTier > 0) {\n\t\t\tpath += `?optimize_streaming_latency=${latencyTier}`;\n\t\t}\n\n\t\tconst response = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\tAccept: 'audio/mpeg',\n\t\t\t\t'xi-api-key': this.apiKey\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`Stream TTS failed: ${response.status}: ${text}`);\n\t\t}\n\n\t\treturn response.body;\n\t}\n\n\t/**\n\t * Convert text to speech (non-streaming)\n\t */\n\tasync convertTTS(voiceId: string, payload: TTSRequest): Promise<Buffer> {\n\t\tconst path = `/v1/text-to-speech/${voiceId}`;\n\n\t\tconst response = await fetch(`${this.baseUrl}${path}`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\tAccept: 'audio/mpeg',\n\t\t\t\t'xi-api-key': this.apiKey\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(`Convert TTS failed: ${response.status}: ${text}`);\n\t\t}\n\n\t\tconst arrayBuffer = await response.arrayBuffer();\n\t\treturn Buffer.from(arrayBuffer);\n\t}\n}\n\n/**\n * Get API key from environment or throw\n */\nexport function getApiKey(providedKey?: string): string {\n\tconst key =\n\t\tprovidedKey ||\n\t\tprocess.env.ELEVENLABS_API_KEY ||\n\t\tprocess.env.AWAZ_API_KEY;\n\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t'Missing ElevenLabs API key. Set --api-key or ELEVENLABS_API_KEY environment variable.'\n\t\t);\n\t}\n\n\treturn key;\n}\n\n/**\n * Get default voice ID from environment\n */\nexport function getDefaultVoiceId(): string | undefined {\n\treturn process.env.ELEVENLABS_VOICE_ID || process.env.AWAZ_VOICE_ID;\n}\n","import pc from 'picocolors';\n\nexport const banner = `\n${pc.white('▄▀█ █░█░█ ▄▀█ ▀█')}\n${pc.gray('█▀█ ▀▄▀▄▀ █▀█ █▄')}\n${pc.dim('text to speech cli.')}\n`;\n\nexport function showBanner(): void {\n\tconsole.log(banner);\n}\n","import pc from 'picocolors';\n\nexport function error(msg: string): void {\n\tconsole.error(`${pc.red('✖')} ${msg}`);\n}\n\nexport function warn(msg: string): void {\n\tconsole.error(`${pc.yellow('⚠')} ${msg}`);\n}\n\nexport function info(msg: string): void {\n\tconsole.error(`${pc.blue('ℹ')} ${msg}`);\n}\n\nexport function success(msg: string): void {\n\tconsole.error(`${pc.green('✔')} ${msg}`);\n}\n\nexport function dim(msg: string): string {\n\treturn pc.dim(msg);\n}\n\nexport function bold(msg: string): string {\n\treturn pc.bold(msg);\n}\n\nexport function cyan(msg: string): string {\n\treturn pc.cyan(msg);\n}\n\nexport function yellow(msg: string): string {\n\treturn pc.yellow(msg);\n}\n\nexport function green(msg: string): string {\n\treturn pc.green(msg);\n}\n\nexport function red(msg: string): string {\n\treturn pc.red(msg);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\ninterface PackageJson {\n\tname: string;\n\tversion: string;\n\tdescription: string;\n}\n\nlet _packageJson: PackageJson | null = null;\n\nexport function getPackageJson(): PackageJson {\n\tif (_packageJson) {\n\t\treturn _packageJson;\n\t}\n\n\t// Try to find package.json, walking up from current file\n\tlet dir = __dirname;\n\tfor (let i = 0; i < 5; i++) {\n\t\tconst pkgPath = path.join(dir, 'package.json');\n\t\tif (fs.existsSync(pkgPath)) {\n\t\t\t_packageJson = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as PackageJson;\n\t\t\treturn _packageJson;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n\n\t// Fallback\n\treturn {\n\t\tname: 'awaz',\n\t\tversion: '0.0.1',\n\t\tdescription: 'Text to speech. Done right.'\n\t};\n}\n\nexport function getVersion(): string {\n\treturn getPackageJson().version;\n}\n","export function padRight(str: string, len: number): string {\n\tif (str.length >= len) return str.slice(0, len);\n\treturn str + ' '.repeat(len - str.length);\n}\n","import { Command } from 'commander';\nimport ora from 'ora';\nimport { ElevenLabsClient, getApiKey } from '../lib/elevenlabs.js';\nimport { log, padRight } from '../utils/index.js';\n\ninterface VoicesOptions {\n\tsearch?: string;\n\tlimit: number;\n\tapiKey?: string;\n\tbaseUrl: string;\n}\n\nexport function createVoicesCommand(): Command {\n\treturn new Command('voices')\n\t\t.description('List voices')\n\t\t.option('--search <query>', 'Filter by name')\n\t\t.option('--limit <n>', 'Max results (0 = all)', '100')\n\t\t.action(async function (this: Command) {\n\t\t\tconst opts = this.optsWithGlobals<VoicesOptions>();\n\t\t\tconst limit = parseInt(String(opts.limit), 10);\n\n\t\t\tconst spinner = ora('Fetching voices...').start();\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = getApiKey(opts.apiKey);\n\t\t\t\tconst client = new ElevenLabsClient({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tbaseUrl: opts.baseUrl\n\t\t\t\t});\n\n\t\t\t\tlet voices = await client.listVoices(opts.search);\n\t\t\t\tspinner.stop();\n\n\t\t\t\tif (limit > 0 && voices.length > limit) {\n\t\t\t\t\tvoices = voices.slice(0, limit);\n\t\t\t\t}\n\n\t\t\t\t// Print header\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${padRight('VOICE ID', 24)} ${padRight('NAME', 24)} CATEGORY`\n\t\t\t\t);\n\n\t\t\t\t// Print rows\n\t\t\t\tfor (const v of voices) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${padRight(v.voice_id, 24)} ${padRight(v.name, 24)} ${v.category}`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (voices.length === 0) {\n\t\t\t\t\tlog.info('No voices found');\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tspinner.fail('Failed to fetch voices');\n\t\t\t\tlog.error((err as Error).message);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n}\n\n\n","import { Command } from 'commander';\nimport { promptingGuide } from './prompting-guide.js';\n\nexport function createPromptingCommand(): Command {\n\treturn new Command('prompting')\n\t\t.aliases(['prompt', 'guide', 'tips'])\n\t\t.description('Tips for better output')\n\t\t.action(() => {\n\t\t\tconsole.log(promptingGuide.trim());\n\t\t});\n}\n","export const promptingGuide = `# Better results from awaz\n\nWhat you write matters. Here's what works.\n\n## Models\n\n**v3 (default)** — Most expressive. Tags like [whispers], [laughs]. No SSML.\n**v2** — Reliable. SSML pauses work. Predictable.\n**Flash** — Fast. ~75ms. Half the cost.\n**Turbo** — Balanced. ~250ms. Good quality.\n\n## Writing tips\n\nWrite how you'd say it. Short sentences. Natural breaks.\n\n**Punctuation = pacing:**\n- Comma, dash → slight pause\n- Ellipsis... → dramatic pause\n- Period → full stop\n- ! → energy\n\n**Spell it how it sounds.** \"API\" wrong? Try \"A P I\" or \"ay-pee-eye\".\n\n## v3 tags\n\n**Emotions:** [whispers], [shouts], [laughs], [sighs], [sarcastic], [excited]\n**Actions:** [clears throat], [exhales], [swallows]\n**Effects:** [applause], [short pause], [long pause]\n**Experimental:** [strong French accent], [sings]\n\nNot every voice responds to every tag. Experiment.\n\n## Options to customize\n\n**--stability** (0-1)\nHigher = consistent. Lower = varied. v3 uses presets: 0=Creative, 0.5=Natural, 1=Robust.\n\n**--similarity** (0-1)\nHigher = closer to original voice sample.\n\n**--style** (0-1)\nHigher = more expressive. Can get weird if too high.\n\n**--speaker-boost**\nAdds clarity. Sometimes helps.\n\n**--seed**\nSame seed = same output. Good for A/B testing.\n\n## Examples\n\nNatural:\n awaz -v Roger --stability 0.5 \"We shipped today. It worked.\"\n\nFast:\n awaz --model-id eleven_flash_v2_5 \"Quick and cheap.\"\n\nDramatic (v3):\n awaz \"[whispers] Don't move. [short pause] Something's there...\"\n\n## TL;DR\n\n1. v3 for expression, v2 for reliability, Flash for speed\n2. Write naturally\n3. Experiment with tags on v3\n4. Tweak stability/similarity if it sounds off\n`;\n"],"mappings":"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","names":["Command","fs","path","config","path","pc","__dirname","voices","fs","resolve","path","Command","ora","Command","ora","Command","Command","Command"]}
|