{
  "markdown": "# voicebox-cli\n\nA small TypeScript command-line client for the [voicebox](http://127.0.0.1:17493) TTS API. It generates speech from text, waits for the async job to finish, downloads the audio, and optionally transcodes it to MP3 or Opus.\n\n## Requirements\n\n- Node.js 20+ (developed on v24)\n- A running voicebox API (defaults to `http://127.0.0.1:17493`)\n\n`ffmpeg` is **not** required on your system — the bundled [`ffmpeg-static`](https://www.npmjs.com/package/ffmpeg-static) binary is used for transcoding.\n\n## Install\n\nRun it directly with `npx`:\n\n```bash\nnpx voicebox-cli speak \"Hello, world!\" --profile Test --output hello.mp3\n```\n\nOr install it globally:\n\n```bash\nnpm install -g voicebox-cli\nvoicebox-cli speak \"Hello, world!\" --profile Test --output hello.mp3\n```\n\n## Usage\n\nOnce installed, the `voicebox-cli` binary is available. Run any command through `npx`:\n\n```bash\nnpx voicebox-cli speak \"Hello, world!\" --profile Test --output outputs/hello.mp3\n```\n\n### `speak`\n\nSynthesize speech from text with a chosen voice profile and save it to a file. The command submits the text to the API, waits for the asynchronous generation to complete, downloads the resulting audio, and writes it locally. Pick the voice with `--profile`, steer synthesis with `--language` and `--engine`, and use `--personality` to rewrite the text in the profile's character before it is spoken.\n\n```\nnpx voicebox-cli speak <text> [options]\n\nOptions:\n  -p, --profile <profile>    voice profile name or id\n  -o, --output <path>        output file (.mp3 or .wav)      (default: speech.mp3)\n  -e, --engine <engine>      TTS engine\n  -l, --language <language>  language code (e.g. en, fr, ja)\n  --personality              rewrite the text in-character before TTS\n  --base-url <url>           API base url\n  -h, --help                 display help for command\n```\n\nThe output format is chosen from the file extension: `.mp3` transcodes via `ffmpeg-static`, anything else writes the raw WAV returned by the API.\n\nExamples:\n\n```bash\n# Simplest: text + voice profile → speech.mp3 (the default output)\nnpx voicebox-cli speak \"Hello there\" --profile Test\n\n# Save to a specific MP3 file\nnpx voicebox-cli speak \"Hello there\" --profile Test --output outputs/hello.mp3\n\n# Save as WAV instead (any non-.mp3 extension writes raw WAV)\nnpx voicebox-cli speak \"Hello there\" --profile Test --output outputs/hello.wav\n\n# French, with a French voice\nnpx voicebox-cli speak \"Bonjour tout le monde !\" --profile manukipu --language fr\n\n# Rewrite the text in the profile's character before speaking\nnpx voicebox-cli speak \"Tell me about your day.\" --profile donaldy --personality\n\n# Pick a specific engine\nnpx voicebox-cli speak \"Testing the kokoro engine.\" --profile Test --engine kokoro\n\n# Point at a server on another host/port\nnpx voicebox-cli speak \"Remote server test.\" --profile Test --base-url http://192.168.1.50:17493\n\n# Using short flags\nnpx voicebox-cli speak \"Short and sweet.\" -p Test -o outputs/quick.mp3\n```\n\n### `generate`\n\nThe low-level counterpart to `speak`. It targets a profile by **id** (not name) and exposes the full generation request: seed, instruction/style prompt, model size, engine, chunking for long text, crossfade, and volume normalization. It also manages the lifecycle of an existing generation — retry a failed one, regenerate from scratch, cancel an in-progress job, or wait on its status.\n\n```\nnpx voicebox-cli generate run <profile-id> <text> [options]\nnpx voicebox-cli generate retry <id>\nnpx voicebox-cli generate regenerate <id>\nnpx voicebox-cli generate cancel <id>\nnpx voicebox-cli generate status <id>\n\nrun options:\n  -o, --output <path>    output file (.mp3 or .wav)   (default: outputs/generation.mp3)\n  -l, --language <code>  language code                (default: en)\n  --seed <n>             random seed\n  --model-size <size>    model size (e.g. 1.7B)\n  --instruct <text>      instruction / style prompt\n  -e, --engine <engine>  TTS engine\n  --personality          rewrite the text in-character before TTS\n  --max-chunk-chars <n>  max characters per chunk for long text\n  --crossfade-ms <n>     crossfade between chunks in ms\n  --no-normalize         do not normalize output volume\n  --base-url <url>       API base url\n```\n\n```bash\nnpx voicebox-cli generate run <profile-id> \"A precise, reproducible take.\" --seed 42 -o outputs/take.wav\n```\n\n### `profiles`\n\nCreate, inspect, and delete the voice profiles that `speak` uses, and manage the reference samples a cloned voice is built from. A profile bundles a voice's language, engine defaults, and an optional personality prompt; samples are short audio clips plus their transcripts that teach the clone how the voice sounds. `update` merges your changes with the profile's current values, so you only pass the fields you want to change.\n\n```\nnpx voicebox-cli profiles <subcommand> [options]\n\nSubcommands:\n  list                              list all profiles\n  get <id>                          show a single profile (JSON)\n  create <name> [options]           create a profile\n  update <id> [options]             update a profile (merges with current values)\n  delete <id>                       delete a profile\n  presets <engine>                  list preset voices for an engine\n  export <id> [-o <path>]           export a profile to a file (default: outputs/profile.zip)\n  samples list <profile-id>         list a profile's reference samples\n  samples add <profile-id> <file> <reference-text>   add a sample from an audio file\n  samples update <sample-id> <reference-text>         change a sample's transcript\n  samples delete <sample-id>        delete a sample\n```\n\n`create` / `update` options:\n\n```\n  -n, --name <name>            profile name (update only)\n  -d, --description <text>     description\n  -l, --language <code>        language code (default: en)\n  --voice-type <type>          voice type (e.g. cloned)\n  --preset-engine <engine>     preset engine\n  --preset-voice-id <id>       preset voice id\n  --design-prompt <text>       voice design prompt\n  --default-engine <engine>    default TTS engine\n  --personality <text>         in-character personality prompt\n  --base-url <url>             API base url\n```\n\n```bash\n# create a profile, then clone a voice into it from a reference clip\nnpx voicebox-cli profiles create \"Narrator\" --language en --personality \"calm and warm\"\nnpx voicebox-cli profiles samples add <profile-id> sample.wav \"This is my reference voice.\"\n\n# list profiles, then generate with one\nnpx voicebox-cli profiles list\nnpx voicebox-cli speak \"Hello there\" --profile Narrator -o outputs/hello.mp3\n```\n\n### `channels`\n\nManage audio output channels and the voices assigned to them. A channel is a named output route that binds a set of audio devices to a set of voice profiles, letting the server play different voices through different speakers. Use these subcommands to create channels, attach output devices, and control which profiles belong to each one.\n\n```\nnpx voicebox-cli channels <subcommand> [options]\n\nSubcommands:\n  list                              list all channels\n  get <id>                          show a single channel (JSON)\n  create <name> [--device <id...>]  create a channel\n  update <id> [-n <name>] [--device <id...>]   update a channel\n  delete <id>                       delete a channel\n  voices <id>                       list profiles assigned to a channel\n  set-voices <id> <profile-ids...>  assign profiles to a channel\n```\n\n```bash\nnpx voicebox-cli channels create \"Living room\" --device dev-1 --device dev-2\nnpx voicebox-cli channels set-voices <channel-id> <profile-id-a> <profile-id-b>\n```\n\n### `history`\n\nBrowse and manage past generations. `list` supports filtering by profile and free-text search with pagination; `get` and `stats` inspect a single item or aggregate totals; `favorite`, `delete`, and `clear-failed` manage entries; and `export` / `export-audio` save a generation's archive or audio to disk.\n\n```\nnpx voicebox-cli history list [-p <profile-id>] [-s <search>] [--limit <n>] [--offset <n>]\nnpx voicebox-cli history get <id>\nnpx voicebox-cli history stats\nnpx voicebox-cli history favorite <id>\nnpx voicebox-cli history delete <id>\nnpx voicebox-cli history clear-failed\nnpx voicebox-cli history export <id> [-o <path>]          # zip (default: outputs/<id>.zip)\nnpx voicebox-cli history export-audio <id> [-o <path>]    # wav (default: outputs/<id>.wav)\n```\n\n```bash\nnpx voicebox-cli history list --profile <profile-id> --search \"hello\" --limit 20\nnpx voicebox-cli history export-audio <id> -o outputs/take.wav\n```\n\n### `models`\n\nManage the TTS models the server can use. `status` lists every model with its download and loaded state; `load` and `unload` control what sits in memory; `download`, `download-wait`, `cancel-download`, and `delete` manage what is on disk; `cache-dir` shows where models are stored; and `progress`, `migrate`, and `migrate-progress` stream live progress from download and directory-migration tasks.\n\n```\nnpx voicebox-cli models status\nnpx voicebox-cli models load [size]                      # size defaults to the server default\nnpx voicebox-cli models unload [name]                    # no name unloads the default model\nnpx voicebox-cli models download <name>                  # triggers the download, returns immediately\nnpx voicebox-cli models download-wait <name>             # downloads, shows progress, blocks until done\nnpx voicebox-cli models cancel-download <name>\nnpx voicebox-cli models delete <name>\nnpx voicebox-cli models cache-dir\nnpx voicebox-cli models progress <name>                  # streams SSE progress\nnpx voicebox-cli models migrate <destination>            # streams SSE progress\nnpx voicebox-cli models migrate-progress                 # streams SSE progress\n```\n\n```bash\nnpx voicebox-cli models status\nnpx voicebox-cli models load 1.7B\nnpx voicebox-cli models download qwen-1.7b\n\n# Download a transcription model and wait until it is ready to use\nnpx voicebox-cli models download-wait whisper-large\n```\n\n### `stories`\n\nAssemble multi-clip stories from existing generations on a timeline and export them as one mixed audio file. The top-level subcommands manage stories themselves (`list`, `get`, `create`, `update`, `delete`, `export-audio`); the `stories items` subgroup manages the clips on a story's timeline — adding, removing, reordering, moving, trimming, adjusting per-clip volume, splitting, duplicating, and pinning a clip to a specific generation version.\n\n```\nnpx voicebox-cli stories list\nnpx voicebox-cli stories get <id>\nnpx voicebox-cli stories create <name> [-d <description>]\nnpx voicebox-cli stories update <id> <name> [-d <description>]\nnpx voicebox-cli stories delete <id>\nnpx voicebox-cli stories export-audio <id> [-o <path>]        # wav (default: outputs/<id>.wav)\n\nnpx voicebox-cli stories items add <story-id> <generation-id> [--start-time-ms <n>] [--track <n>]\nnpx voicebox-cli stories items remove <story-id> <item-id>\nnpx voicebox-cli stories items times <story-id> <gen-id:ms>...   # e.g. g1:0 g2:2500\nnpx voicebox-cli stories items reorder <story-id> <generation-id>...\nnpx voicebox-cli stories items move <story-id> <item-id> <start-time-ms> [--track <n>]\nnpx voicebox-cli stories items trim <story-id> <item-id> <trim-start-ms> <trim-end-ms>\nnpx voicebox-cli stories items volume <story-id> <item-id> <volume>   # linear gain 0.0-2.0\nnpx voicebox-cli stories items split <story-id> <item-id> <split-time-ms>\nnpx voicebox-cli stories items duplicate <story-id> <item-id>\nnpx voicebox-cli stories items version <story-id> <item-id> [version-id]   # omit to clear the pin\n```\n\nExamples:\n\n```bash\n# Create a story and add two generations to its timeline\nnpx voicebox-cli stories create \"Chapter 1\" --description \"The opening scene\"\nnpx voicebox-cli stories items add <story-id> <generation-id>\nnpx voicebox-cli stories items add <story-id> <generation-id> --start-time-ms 3000\n\n# Reorder by generation id, then export the mixed audio\nnpx voicebox-cli stories items reorder <story-id> <gen-a> <gen-b>\nnpx voicebox-cli stories export-audio <story-id> -o outputs/chapter1.wav\n\n# Fine-tune a single clip\nnpx voicebox-cli stories items volume <story-id> <item-id> 0.8\nnpx voicebox-cli stories items trim <story-id> <item-id> 250 100\n```\n\n### `transcribe`\n\nTranscribe an audio file to text. Pass the file path and, optionally, a language hint and a transcription model. By default it prints just the transcript; add `--json` to get the raw response including the audio duration. Non-WAV inputs (MP3, Opus, FLAC, and anything else ffmpeg can read) are transcoded to WAV locally before upload.\n\n```\nnpx voicebox-cli transcribe <file> [options]\n\nOptions:\n  -l, --language <language>  language hint (one of: zh, en, ja, ...; pass 'list' to see options)\n  -m, --model <model>        transcription model (one of: whisper-base, whisper-small, whisper-medium, whisper-large, whisper-turbo; pass 'list' to see options)\n  --json                     print the raw JSON response\n  --base-url <url>           API base url\n  -h, --help                 display help for command\n```\n\nExamples:\n\n```bash\n# Simplest: audio file → transcript printed to stdout\nnpx voicebox-cli transcribe outputs/take.wav\n\n# MP3 (or any ffmpeg-readable format) is converted to WAV automatically\nnpx voicebox-cli transcribe outputs/take.mp3\n\n# Give a language hint for better accuracy\nnpx voicebox-cli transcribe outputs/take.wav --language en\n\n# Pick a specific transcription model (whisper-base, whisper-small, whisper-medium, whisper-large, whisper-turbo)\nnpx voicebox-cli transcribe outputs/take.wav --model whisper-turbo\n\n# Pass 'list' to any enum option to print its accepted values\nnpx voicebox-cli transcribe outputs/take.wav --model list\n\n# Get the raw JSON (includes the audio duration)\nnpx voicebox-cli transcribe outputs/take.wav --json\n\n# Save the transcript to a text file\nnpx voicebox-cli transcribe outputs/take.wav > outputs/take.txt\n\n# Point at a server on another host/port\nnpx voicebox-cli transcribe outputs/take.wav --base-url http://192.168.1.50:17493\n\n# Using short flags\nnpx voicebox-cli transcribe outputs/take.wav -l en -m whisper-turbo\n```\n\n### `health`\n\nReport the API's status: whether the model is loaded, which backend and GPU are in use, and any compatibility warnings. Pass `-f`/`--filesystem` to instead check that the server's storage directories exist, are writable, and have free disk space. Add `--json` to print the raw response for scripting.\n\n```\nnpx voicebox-cli health [options]\n\nOptions:\n  -f, --filesystem  check filesystem health instead\n  --json            print the raw JSON response\n  --base-url <url>  API base url\n```\n\n```bash\n$ npx voicebox-cli health\nstatus: healthy\nmodel: loaded (1.7B)\ngpu: MPS (Apple Silicon)\nbackend: mlx (cpu)\n```\n\n### `shutdown`\n\nGracefully shut down the API server. Because this stops the process that serves every other command, it refuses to run unless you pass `--yes` to confirm. Point it at a specific server with `--base-url`.\n\n```\nnpx voicebox-cli shutdown [options]\n\nOptions:\n  -y, --yes         skip the confirmation prompt\n  --base-url <url>  API base url\n```\n\n```bash\nnpx voicebox-cli shutdown --yes\n```\n\n### `watchdog`\n\nControl the server's parent-process watchdog. By default the server shuts itself down when the process that launched it goes away; `watchdog disable` turns that off so the server keeps running on its own. This is useful when you started the server from a short-lived launcher but want it to persist.\n\n```\nnpx voicebox-cli watchdog disable [options]\n\nOptions:\n  --base-url <url>  API base url\n```\n\n### `install`\n\nInstall the bundled voicebox **skill** into an AI agent folder so an assistant such as Claude Code knows how to drive this CLI. It copies the `SKILL.md` tree into `<agent-folder>/skills/voicebox/`. The folder defaults to the current directory; pass a `.claude` folder (or any agent folder) to target a specific one.\n\n```\nnpx voicebox-cli install [agent-folder]\n```\n\n```bash\n# Install into ./.claude for the current project (the usual case)\nnpx voicebox-cli install .claude\n\n# Install into the current directory (the default when no folder is given)\nnpx voicebox-cli install\n```\n\n## Use as an AI agent skill\n\nvoicebox-cli ships a [SKILL.md](dotclaude_folder/skills/voicebox/SKILL.md) that teaches an AI coding agent (e.g. Claude Code) how to use these commands for text-to-speech and transcription. Install it into a project's agent folder with:\n\n```bash\nnpx voicebox-cli install .claude\n```\n\nThe bundled skill lives under `dotclaude_folder/skills/`, mirroring the `.claude/skills/` layout. When developing this repo, mirror `dotclaude_folder/` into the repo's own `.claude/` as symlinks so the skill is live while its source stays tracked:\n\n```bash\nnpm run symlink:dotclaude\n```\n\n## Output formats\n\nThe API serves WAV; the CLI transcodes locally.\n\n| Extension | Codec | Notes |\n| --- | --- | --- |\n| `.wav` | PCM | Uncompressed, universal |\n| `.mp3` | libmp3lame | Small, widely supported |\n\nFor a royalty-free, WhatsApp/Chromium-friendly format, transcode to Opus with the bundled binary:\n\n```bash\nnode_modules/ffmpeg-static/ffmpeg -i outputs/speech.mp3 -c:a libopus -b:a 96k outputs/speech.ogg\n```\n\n## Project layout\n\n```\nsrc/\n  cli.ts                  # Commander entry point\n  commands/\n    speak_command.ts      # `speak` command\n    generate_command.ts   # `generate` command group\n    profiles_command.ts   # `profiles` command group\n    channels_command.ts   # `channels` command group\n    history_command.ts    # `history` command group\n    models_command.ts     # `models` command group\n    stories_command.ts    # `stories` command group\n    transcribe_command.ts # `transcribe` command\n    health_command.ts     # `health` command\n    shutdown_command.ts   # `shutdown` command\n    watchdog_command.ts   # `watchdog` command\n    install_command.ts    # `install` command (copies the bundled skill)\n  misc/\n    voicebox_client.ts    # VoiceboxClient — /speak, /profiles, status stream, audio download\n    audio_convert.ts      # AudioConvert — WAV → MP3 via ffmpeg-static\ndotclaude_folder/\n  skills/\n    voicebox/\n      SKILL.md            # bundled agent skill, installed by `install`\nscripts/\n  symlink_dotclaude.sh    # mirror dotclaude_folder/ into .claude/ for local dev\nexamples/\n  generate_speech.ts      # library usage without the CLI\noutputs/                  # generated audio (git-ignored)\n```\n\n## Programmatic use\n\n```ts\nimport { VoiceboxClient } from './src/misc/voicebox_client.js';\n\nconst client = new VoiceboxClient();\nconst generation = await client.speak({ text: 'Hello', profile: 'Test' });\nconst final = await client.waitForCompletion(generation.id);\nconst wav = await client.downloadAudio(final.id);\n```\n\n## Scripts\n\n```bash\nnpm run cli               # run the CLI\nnpm run symlink:dotclaude # mirror dotclaude_folder/ into .claude/ (local dev)\nnpm run typecheck         # tsc against tsconfig.json\nnpm run build             # emit dist/ via tsconfig.build.json\n```\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 19034,
  "sha": "7ebaa36ccb2dcf92371a88d61417d12e8ec64ff707cf70ed924750ea7162ebfd",
  "repo_slug": "jeromeetienne/voicebox_cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_jeromeetienne_voicebox_cli_okf_index_md_73ff2fd8/readme"
}