@drakulavich/kesha-voice-kit 1.24.3 → 1.24.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/package.json +5 -2
- package/src/cli/dispatch.ts +55 -32
- package/src/cli/init.ts +3 -16
- package/src/cli/install.ts +2 -12
- package/src/cli/main.ts +264 -172
- package/src/cli/say.ts +113 -91
- package/src/cli/types.ts +17 -0
- package/src/cli.ts +2 -1
- package/src/doctor.ts +63 -38
- package/src/engine-install.ts +99 -122
- package/src/engine-version-marker.ts +0 -1
- package/src/engine.ts +9 -41
- package/src/install-plan.ts +142 -126
- package/src/lib.ts +1 -2
- package/src/log.ts +2 -11
- package/src/star.ts +8 -32
- package/src/status.ts +60 -62
- package/src/synth.ts +25 -42
- package/src/types.ts +1 -6
- package/src/voice-routing.ts +1 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakulavich/kesha-voice-kit",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.4",
|
|
4
4
|
"description": "Give your tools a voice — speech to text and back, 25 languages, up to ~19× faster than Whisper. On your machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"keshaEngine": {
|
|
41
|
-
"version": "1.24.
|
|
41
|
+
"version": "1.24.4"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"test": "bun test",
|
|
@@ -99,5 +99,8 @@
|
|
|
99
99
|
"picocolors": "^1.1.1",
|
|
100
100
|
"tinyld": "^1.3.4",
|
|
101
101
|
"zod": "^4.4.3"
|
|
102
|
+
},
|
|
103
|
+
"overrides": {
|
|
104
|
+
"hono": "^4.12.25"
|
|
102
105
|
}
|
|
103
106
|
}
|
package/src/cli/dispatch.ts
CHANGED
|
@@ -46,9 +46,7 @@ function isFalsey(v: string): boolean {
|
|
|
46
46
|
return FALSEY_VALUES.has(v.trim().toLowerCase());
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
//
|
|
50
|
-
// once at import (before any runCli) so re-enabling colors never clobbers an
|
|
51
|
-
// externally-set NO_COLOR — we only clear the var on re-enable when WE set it.
|
|
49
|
+
// Captured at import so re-enabling colors never clobbers a user-exported NO_COLOR.
|
|
52
50
|
const USER_FORCED_NO_COLOR =
|
|
53
51
|
process.env.NO_COLOR !== undefined && !isFalsey(process.env.NO_COLOR);
|
|
54
52
|
|
|
@@ -105,47 +103,72 @@ export function resolveQuietMode(rawArgs: string[]): { quiet: boolean; rawArgs:
|
|
|
105
103
|
return { quiet: value, rawArgs: cleaned };
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// by a later in-process call: set it when WE disable, clear it on re-enable —
|
|
119
|
-
// but never clear a NO_COLOR the user exported themselves.
|
|
120
|
-
if (color.disableColor) {
|
|
106
|
+
/**
|
|
107
|
+
* Sync NO_COLOR with the resolved color decision so engine subprocesses inherit
|
|
108
|
+
* the right value. Separated from setColorEnabled so it can be tested without
|
|
109
|
+
* picocolors side-effects.
|
|
110
|
+
*
|
|
111
|
+
* Never clears a NO_COLOR the user exported before this process started
|
|
112
|
+
* (USER_FORCED_NO_COLOR guard).
|
|
113
|
+
*/
|
|
114
|
+
export function applyColorEnv(disableColor: boolean): void {
|
|
115
|
+
if (disableColor) {
|
|
121
116
|
process.env.NO_COLOR = "1";
|
|
122
117
|
} else if (!USER_FORCED_NO_COLOR) {
|
|
123
118
|
delete process.env.NO_COLOR;
|
|
124
119
|
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Classify the first positional arg for routing.
|
|
124
|
+
*
|
|
125
|
+
* - `"subcommand"` — exact match in the known subcommand set
|
|
126
|
+
* - `"unknown"` — bare token that looks like a typo (not a flag, not path-like)
|
|
127
|
+
* - `"main"` — flags, path-like args, or no arg (→ transcribe / help)
|
|
128
|
+
*/
|
|
129
|
+
export function classifyFirstArg(
|
|
130
|
+
firstArg: string | undefined,
|
|
131
|
+
subcommandKeys: string[],
|
|
132
|
+
): "subcommand" | "unknown" | "main" {
|
|
133
|
+
if (!firstArg) return "main";
|
|
134
|
+
if (subcommandKeys.includes(firstArg)) return "subcommand";
|
|
135
|
+
// Flags and path-like tokens fall through to the main transcribe command.
|
|
136
|
+
if (firstArg.startsWith("-") || isPathLike(firstArg)) return "main";
|
|
137
|
+
return "unknown";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function runCli(rawArgs = process.argv.slice(2)): Promise<void> {
|
|
141
|
+
// Global flags resolved before citty so they apply to every command and never reach a subcommand's arg schema.
|
|
142
|
+
const color = resolveColorMode(rawArgs);
|
|
143
|
+
// Reset on every invocation so an earlier --no-color/CI call doesn't leave colors off for later in-process calls (unit tests, `kesha mcp`).
|
|
144
|
+
setColorEnabled(!color.disableColor);
|
|
145
|
+
applyColorEnv(color.disableColor);
|
|
125
146
|
|
|
126
147
|
const quiet = resolveQuietMode(color.rawArgs);
|
|
127
148
|
log.quietEnabled = quiet.quiet;
|
|
128
149
|
|
|
129
150
|
rawArgs = quiet.rawArgs;
|
|
130
151
|
const [firstArg, ...restArgs] = rawArgs;
|
|
152
|
+
const subcommandKeys = Object.keys(SUBCOMMANDS);
|
|
131
153
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
154
|
+
switch (classifyFirstArg(firstArg, subcommandKeys)) {
|
|
155
|
+
case "subcommand":
|
|
156
|
+
await runMain(SUBCOMMANDS[firstArg!], { rawArgs: restArgs });
|
|
157
|
+
return;
|
|
136
158
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
log.warn(`
|
|
159
|
+
case "unknown": {
|
|
160
|
+
// Extensionless existing files are valid transcription inputs; bare non-path tokens are likely command typos.
|
|
161
|
+
const suggestion = suggestCommand(firstArg!, subcommandKeys);
|
|
162
|
+
log.error(`unknown command '${firstArg}'`);
|
|
163
|
+
if (suggestion && suggestion !== firstArg) {
|
|
164
|
+
log.warn(`(Did you mean ${suggestion}?)`);
|
|
165
|
+
}
|
|
166
|
+
log.warn(`If this is an audio file, pass a path like './${firstArg}'.`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
break;
|
|
145
169
|
}
|
|
146
|
-
log.warn(`If this is an audio file, pass a path like './${firstArg}'.`);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
170
|
|
|
150
|
-
|
|
171
|
+
default:
|
|
172
|
+
await runMain(mainCommand, { rawArgs });
|
|
173
|
+
}
|
|
151
174
|
}
|
package/src/cli/init.ts
CHANGED
|
@@ -5,12 +5,8 @@ import { multiselect, isCancel, cancel } from "@clack/prompts";
|
|
|
5
5
|
import { renderInstallPlan } from "../install-plan";
|
|
6
6
|
import { log } from "../log";
|
|
7
7
|
import { getEngineCapabilities } from "../engine";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
resolveBackendFlag,
|
|
11
|
-
resolveNoCacheFlag,
|
|
12
|
-
TTS_LANG_FALLBACK,
|
|
13
|
-
} from "./install";
|
|
8
|
+
import { performInstall, resolveBackendFlag, resolveNoCacheFlag, TTS_LANG_FALLBACK } from "./install";
|
|
9
|
+
import type { SharedInstallArgs } from "./types";
|
|
14
10
|
|
|
15
11
|
const TTS_LANG_LABELS: Record<string, string> = {
|
|
16
12
|
en: "English (Kokoro)",
|
|
@@ -44,16 +40,7 @@ async function promptTtsLangs(preselect: string[]): Promise<string[]> {
|
|
|
44
40
|
return selected as string[];
|
|
45
41
|
}
|
|
46
42
|
|
|
47
|
-
export interface InitCommandArgs {
|
|
48
|
-
coreml: boolean;
|
|
49
|
-
onnx: boolean;
|
|
50
|
-
"no-cache": boolean;
|
|
51
|
-
noCache?: boolean;
|
|
52
|
-
no_cache?: boolean;
|
|
53
|
-
tts: boolean;
|
|
54
|
-
vad: boolean;
|
|
55
|
-
diarize: boolean;
|
|
56
|
-
plan: boolean;
|
|
43
|
+
export interface InitCommandArgs extends SharedInstallArgs {
|
|
57
44
|
yes: boolean;
|
|
58
45
|
}
|
|
59
46
|
|
package/src/cli/install.ts
CHANGED
|
@@ -7,19 +7,11 @@ import { maybeAskForStar } from "../star";
|
|
|
7
7
|
import { log } from "../log";
|
|
8
8
|
import { packageVersion } from "../package-info";
|
|
9
9
|
import { createDiagnosticLogSession, type DiagnosticLogSession } from "../diagnostic-log";
|
|
10
|
+
import type { SharedInstallArgs } from "./types";
|
|
10
11
|
|
|
11
|
-
export interface InstallCommandArgs {
|
|
12
|
+
export interface InstallCommandArgs extends SharedInstallArgs {
|
|
12
13
|
/** Positional args after `install` — candidate TTS language codes. */
|
|
13
14
|
_?: string[];
|
|
14
|
-
coreml: boolean;
|
|
15
|
-
onnx: boolean;
|
|
16
|
-
"no-cache": boolean;
|
|
17
|
-
noCache?: boolean;
|
|
18
|
-
no_cache?: boolean;
|
|
19
|
-
tts: boolean;
|
|
20
|
-
vad: boolean;
|
|
21
|
-
diarize: boolean;
|
|
22
|
-
plan: boolean;
|
|
23
15
|
}
|
|
24
16
|
|
|
25
17
|
/**
|
|
@@ -30,9 +22,7 @@ export interface InstallCommandArgs {
|
|
|
30
22
|
export const TTS_LANG_FALLBACK = ["en", "es", "fr", "it", "pt", "ru"];
|
|
31
23
|
|
|
32
24
|
export interface TtsArgInput {
|
|
33
|
-
/** Whether --tts was passed. */
|
|
34
25
|
tts: boolean;
|
|
35
|
-
/** Positional args after the install command (candidate language codes). */
|
|
36
26
|
positionals: string[];
|
|
37
27
|
}
|
|
38
28
|
|