@drakulavich/kesha-voice-kit 1.19.0 → 1.20.0

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="docs/assets/logo.png" alt="Kesha Voice Kit" width="200">
2
+ <img src="https://raw.githubusercontent.com/drakulavich/kesha-voice-kit/main/docs/assets/logo.png" alt="Kesha Voice Kit" width="200">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Kesha Voice Kit</h1>
@@ -21,7 +21,7 @@
21
21
  See [Product positioning](docs/product-positioning.md) for supported workflows, non-goals, maturity labels, and the platform matrix.
22
22
 
23
23
  <p align="center">
24
- <img src="./demo.gif" alt="kesha demo — English + Russian transcription with automatic language detection" width="800">
24
+ <img src="https://raw.githubusercontent.com/drakulavich/kesha-voice-kit/main/demo.gif" alt="kesha demo — English + Russian transcription with automatic language detection" width="800">
25
25
  </p>
26
26
 
27
27
  ## Quick Start
@@ -104,6 +104,16 @@ kesha say "Hello, world" > hello.wav
104
104
  kesha say "Привет, мир" > privet.wav # auto-routes (Milena on darwin, ru-vosk-m02 elsewhere)
105
105
  ```
106
106
 
107
+ **Output formats** (`--format`, or inferred from `--out` extension):
108
+
109
+ ```bash
110
+ kesha say "Hello" --out hi.wav # WAV (default, uncompressed)
111
+ kesha say "Hello" --format ogg-opus --out hi.ogg # OGG/Opus — messenger voice notes (Telegram/WhatsApp/Signal)
112
+ kesha say "Hello" --format flac --out hi.flac # FLAC — lossless, royalty-free, plays in every browser incl. Safari/iOS
113
+ ```
114
+
115
+ FLAC is the format for web-embeddable samples: it plays natively in all modern browsers (including Safari/iOS, where OGG/Opus does not), stays royalty-free like Opus, and keeps the engine's native sample rate (no resample). `--bitrate` / `--sample-rate` apply only to `--format ogg-opus`.
116
+
107
117
  **Russian abbreviations** (`ru-vosk-*`): all-uppercase Cyrillic 2-5-char tokens auto-expand letter-by-letter when not pronounceable as a Russian syllable (ФСБ → "эф-эс-бэ", ВОЗ → "воз"). Disable with `--no-expand-abbrev`. See [docs/tts.md#russian-abbreviation-auto-expansion](docs/tts.md#russian-abbreviation-auto-expansion).
108
118
 
109
119
  **English acronyms** (`en-*`, Kokoro): three-table mechanism (letter-spell rule + STOP_LIST + IPA_LEXICON) auto-expands FBI → "ef bee eye" and gives EPAM/JSON/Anthropic the right IPA. Disable letter-spell with `--no-expand-abbrev`. See [docs/tts.md#english-acronym-auto-expansion](docs/tts.md#english-acronym-auto-expansion).
@@ -232,7 +242,7 @@ mandb ~/.local/share/man 2>/dev/null || true
232
242
 
233
243
  Compared against Whisper `large-v3-turbo` — all engines auto-detect language.
234
244
 
235
- ![Benchmark: openai-whisper vs faster-whisper vs Kesha Voice Kit](docs/assets/benchmark.svg)
245
+ ![Benchmark: openai-whisper vs faster-whisper vs Kesha Voice Kit](https://raw.githubusercontent.com/drakulavich/kesha-voice-kit/main/docs/assets/benchmark.svg)
236
246
 
237
247
  See [BENCHMARK.md](BENCHMARK.md) for the full per-file breakdown (Russian + English).
238
248
 
@@ -280,6 +290,10 @@ Cache boundary: `kesha install` and opt-in feature installs populate the local
280
290
  cache; ordinary transcription and speech commands fail fast if required assets
281
291
  are missing.
282
292
 
293
+ Contributors: see [`docs/architecture.md`](docs/architecture.md) for the
294
+ code-level map (repo layout, CLI↔engine boundary, backends, model pinning,
295
+ tests, and a "where to change X" table).
296
+
283
297
  ## What's Inside
284
298
 
285
299
  | Model | Task | Size | Source |
package/SKILL.md CHANGED
@@ -168,6 +168,12 @@ kesha say --list-voices # Kokoro + Vosk-TTS + ~180 ma
168
168
 
169
169
  Output: WAV mono float32 by default. `--out <path>` writes to a file instead of stdout. For Telegram/OpenClaw replies, prefer `--format ogg-opus --out reply.ogg` or the OpenClaw-provided `{{OutputPath}}`.
170
170
 
171
+ **Output formats** (`--format`, or inferred from the `--out` extension): `wav` (default, uncompressed), `ogg-opus` (messenger voice notes), `flac` (lossless, royalty-free, plays in every browser incl. Safari/iOS — the format for web-embeddable samples). FLAC keeps the engine's native rate; `--bitrate` / `--sample-rate` apply only to `ogg-opus`.
172
+
173
+ ```bash
174
+ kesha say --format flac --out sample.flac "Hello" # web-embeddable, Safari-safe
175
+ ```
176
+
171
177
  **Voice notes (Telegram / WhatsApp / Signal / Discord):** add `--format ogg-opus` to emit OGG/Opus directly — the format messenger APIs render as a native voice message:
172
178
 
173
179
  ```bash
@@ -69,7 +69,7 @@ complete -c kesha -n '__fish_seen_subcommand_from say' -l out -r -d 'Write audio
69
69
  complete -c kesha -n '__fish_seen_subcommand_from say' -l rate -r -d 'Speaking rate 0.5–2.0'
70
70
  complete -c kesha -n '__fish_seen_subcommand_from say' -l list-voices -d 'List installed voices and exit'
71
71
  complete -c kesha -n '__fish_seen_subcommand_from say' -l ssml -d 'Parse input as SSML (supports <speak>, <break>; strips unknown tags)'
72
- complete -c kesha -n '__fish_seen_subcommand_from say' -l format -r -d 'Output format: wav (default) or ogg-opus (Telegram-ready voice note). Inferred from --out extension when omitted.'
72
+ complete -c kesha -n '__fish_seen_subcommand_from say' -l format -r -d 'Output format: wav (default), ogg-opus (Telegram-ready voice note), or flac (lossless, plays in all browsers incl. Safari). Inferred from --out extension when omitted.'
73
73
  complete -c kesha -n '__fish_seen_subcommand_from say' -l bitrate -r -d 'Opus bitrate in bits/sec (e.g. 32000). Only with --format ogg-opus.'
74
74
  complete -c kesha -n '__fish_seen_subcommand_from say' -l sample-rate -r -d 'Opus encoder sample rate (8000/12000/16000/24000/48000). Only with --format ogg-opus.'
75
75
  complete -c kesha -n '__fish_seen_subcommand_from say' -l no-expand-abbrev -d 'Disable Russian acronym auto-expansion (ВОЗ → \'вэ о зэ\') for ru-vosk-* voices. <say-as interpret-as=\'characters\'> still works. Applies to Russian (ru-vosk-*) and English (en-*) voices.'
@@ -99,7 +99,7 @@ _kesha() {
99
99
  '--rate=[Speaking rate 0.5–2.0]:rate:' \
100
100
  '--list-voices[List installed voices and exit]' \
101
101
  '--ssml[Parse input as SSML (supports <speak>, <break>; strips unknown tags)]' \
102
- '--format=[Output format: wav (default) or ogg-opus (Telegram-ready voice note). Inferred from --out extension when omitted.]:format:' \
102
+ '--format=[Output format: wav (default), ogg-opus (Telegram-ready voice note), or flac (lossless, plays in all browsers incl. Safari). Inferred from --out extension when omitted.]:format:' \
103
103
  '--bitrate=[Opus bitrate in bits/sec (e.g. 32000). Only with --format ogg-opus.]:bitrate:' \
104
104
  '--sample-rate=[Opus encoder sample rate (8000/12000/16000/24000/48000). Only with --format ogg-opus.]:sample rate:' \
105
105
  '--no-expand-abbrev[Disable Russian acronym auto-expansion (ВОЗ → '\''вэ о зэ'\'') for ru-vosk-* voices. <say-as interpret-as='\''characters'\''> still works. Applies to Russian (ru-vosk-*) and English (en-*) voices.]' \
package/man/kesha.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH KESHA 1 "May 2026" "kesha 1.19.0" "User Commands"
1
+ .TH KESHA 1 "May 2026" "kesha 1.20.0" "User Commands"
2
2
  .SH NAME
3
3
  kesha \- open-source local voice toolkit
4
4
  .SH SYNOPSIS
@@ -167,7 +167,7 @@ List installed voices and exit
167
167
  Parse input as SSML (supports <speak>, <break>; strips unknown tags)
168
168
  .TP
169
169
  .B \-\-format
170
- Output format: wav (default) or ogg\-opus (Telegram\-ready voice note). Inferred from \-\-out extension when omitted.
170
+ Output format: wav (default), ogg\-opus (Telegram\-ready voice note), or flac (lossless, plays in all browsers incl. Safari). Inferred from \-\-out extension when omitted.
171
171
  .TP
172
172
  .B \-\-bitrate
173
173
  Opus bitrate in bits/sec (e.g. 32000). Only with \-\-format ogg\-opus.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drakulavich/kesha-voice-kit",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "description": "Give your local tools a voice: fast STT in 25 languages (~19x faster than Whisper on Apple Silicon, ONNX CPU fallback), TTS via Kokoro/Vosk/macOS voices, VAD + 107-language detection. Rust engine, Bun CLI, OpenClaw skill.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -32,7 +32,7 @@
32
32
  ]
33
33
  },
34
34
  "keshaEngine": {
35
- "version": "1.19.0"
35
+ "version": "1.20.0"
36
36
  },
37
37
  "scripts": {
38
38
  "test": "bun test",
@@ -79,7 +79,7 @@
79
79
  "devDependencies": {
80
80
  "@types/bun": "latest",
81
81
  "@typescript/native-preview": "^7.0.0-dev.20260423.1",
82
- "fast-xml-parser": "^5.5.10",
82
+ "fast-xml-parser": "^5.8.0",
83
83
  "typescript": "^6.0.2",
84
84
  "yaml": "^2.9.0"
85
85
  },
package/src/cli/say.ts CHANGED
@@ -100,7 +100,7 @@ export const sayCommand = defineCommand({
100
100
  format: {
101
101
  type: "string",
102
102
  description:
103
- "Output format: wav (default) or ogg-opus (Telegram-ready voice note). Inferred from --out extension when omitted.",
103
+ "Output format: wav (default), ogg-opus (Telegram-ready voice note), or flac (lossless, plays in all browsers incl. Safari). Inferred from --out extension when omitted.",
104
104
  },
105
105
  bitrate: {
106
106
  type: "string",
@@ -145,12 +145,12 @@ export const sayCommand = defineCommand({
145
145
  const fmtArg = typeof args.format === "string" ? args.format.toLowerCase() : undefined;
146
146
  let format: SayFormat | undefined;
147
147
  if (fmtArg) {
148
- if (fmtArg === "wav" || fmtArg === "ogg-opus") {
148
+ if (fmtArg === "wav" || fmtArg === "ogg-opus" || fmtArg === "flac") {
149
149
  format = fmtArg;
150
150
  } else if (fmtArg === "opus" || fmtArg === "ogg") {
151
151
  format = "ogg-opus";
152
152
  } else {
153
- log.error(`unknown --format '${args.format}'. supported: wav, ogg-opus`);
153
+ log.error(`unknown --format '${args.format}'. supported: wav, ogg-opus, flac`);
154
154
  process.exit(2);
155
155
  }
156
156
  }
@@ -166,7 +166,10 @@ export const sayCommand = defineCommand({
166
166
  ? args.out.split(".").pop()?.toLowerCase()
167
167
  : undefined;
168
168
  const impliesOpus = outExt && ["ogg", "opus", "oga"].includes(outExt);
169
- if (format === "wav" || (format === undefined && !impliesOpus)) {
169
+ // --bitrate / --sample-rate are Opus-only. Reject for wav and flac
170
+ // (both lossless / no encoder knobs) and for any non-Opus extension.
171
+ const resolvesToOpus = format === "ogg-opus" || (format === undefined && impliesOpus);
172
+ if (!resolvesToOpus) {
170
173
  log.error("--bitrate and --sample-rate are only valid with --format ogg-opus");
171
174
  process.exit(2);
172
175
  }
package/src/synth.ts CHANGED
@@ -14,8 +14,10 @@ import { registerProcessTree } from "./process-tree";
14
14
  * - `wav` (default): RIFF WAV at the engine's native sample rate.
15
15
  * - `ogg-opus`: OGG-encapsulated Opus, mono. The format Telegram, WhatsApp,
16
16
  * Signal, and Discord render as native voice messages. See #223.
17
+ * - `flac`: lossless, royalty-free, plays in every modern browser including
18
+ * Safari/iOS. Keeps the engine's native rate; no bitrate knob.
17
19
  */
18
- export type SayFormat = "wav" | "ogg-opus";
20
+ export type SayFormat = "wav" | "ogg-opus" | "flac";
19
21
  export const MAX_TEXT_CHARS = 5000;
20
22
 
21
23
  export interface SayOptions {