@drakulavich/kesha-voice-kit 1.24.3 → 1.24.5
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/bin/kesha.js +1 -1
- package/package.json +6 -5
- package/src/cli/dispatch.ts +71 -62
- 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-entry.ts +8 -0
- package/src/cli.ts +2 -7
- 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/tsconfig.json +1 -2
package/bin/kesha.js
CHANGED
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.5",
|
|
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.5"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"test": "bun test",
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"coverage:check:rust": "bun .github/scripts/check-coverage.ts --preset=rust --lcov=coverage/rust/lcov.info --summary=coverage/rust/summary.md",
|
|
53
53
|
"generate:shell-artifacts": "bun scripts/generate-shell-artifacts.ts",
|
|
54
54
|
"lint": "bunx tsc --noEmit",
|
|
55
|
-
"lint:tsgo": "bunx tsgo --noEmit",
|
|
56
55
|
"check": "bun run lint && bun run check:versions && bun run test:cli-fast",
|
|
57
56
|
"check:workflows": "bun .github/scripts/check-workflows.ts",
|
|
58
57
|
"check:release-manifest": "bun .github/scripts/release-manifest.mjs --check",
|
|
@@ -85,9 +84,8 @@
|
|
|
85
84
|
},
|
|
86
85
|
"devDependencies": {
|
|
87
86
|
"@types/bun": "latest",
|
|
88
|
-
"@typescript/native-preview": "^7.0.0-dev.20260423.1",
|
|
89
87
|
"fast-xml-parser": "^5.8.0",
|
|
90
|
-
"typescript": "^
|
|
88
|
+
"typescript": "^7.0.2",
|
|
91
89
|
"yaml": "^2.9.0"
|
|
92
90
|
},
|
|
93
91
|
"dependencies": {
|
|
@@ -99,5 +97,8 @@
|
|
|
99
97
|
"picocolors": "^1.1.1",
|
|
100
98
|
"tinyld": "^1.3.4",
|
|
101
99
|
"zod": "^4.4.3"
|
|
100
|
+
},
|
|
101
|
+
"overrides": {
|
|
102
|
+
"hono": "^4.12.25"
|
|
102
103
|
}
|
|
103
104
|
}
|
package/src/cli/dispatch.ts
CHANGED
|
@@ -2,37 +2,23 @@ import { runMain, type CommandDef } from "citty";
|
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import { log, setColorEnabled } from "../log";
|
|
4
4
|
import { suggestCommand } from "../suggest-command";
|
|
5
|
-
import { completionsCommand } from "./completions";
|
|
6
|
-
import { doctorCommand } from "./doctor";
|
|
7
|
-
import { initCommand } from "./init";
|
|
8
|
-
import { installCommand } from "./install";
|
|
9
|
-
import { logsCommand } from "./logs";
|
|
10
|
-
import { manpageCommand } from "./manpage";
|
|
11
|
-
import { recordCommand } from "./record";
|
|
12
|
-
import { sayCommand } from "./say";
|
|
13
|
-
import { statsCommand } from "./stats";
|
|
14
|
-
import { statusCommand } from "./status";
|
|
15
|
-
import { supportBundleCommand } from "./support-bundle";
|
|
16
|
-
import { mainCommand } from "./main";
|
|
17
|
-
import { mcpCommand } from "./mcp";
|
|
18
5
|
|
|
19
|
-
//
|
|
20
|
-
// `CommandDef<any
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
mcp: mcpCommand,
|
|
6
|
+
// Lazy loaders so a cold CLI spawn transpiles only the invoked command, not the whole graph (#568).
|
|
7
|
+
// `CommandDef<any>`: citty's generic is invariant in the arg shape and each command has its own schema.
|
|
8
|
+
type CommandLoader = () => Promise<CommandDef<any>>;
|
|
9
|
+
const SUBCOMMANDS: Record<string, CommandLoader> = {
|
|
10
|
+
doctor: async () => (await import("./doctor")).doctorCommand,
|
|
11
|
+
init: async () => (await import("./init")).initCommand,
|
|
12
|
+
install: async () => (await import("./install")).installCommand,
|
|
13
|
+
logs: async () => (await import("./logs")).logsCommand,
|
|
14
|
+
status: async () => (await import("./status")).statusCommand,
|
|
15
|
+
record: async () => (await import("./record")).recordCommand,
|
|
16
|
+
say: async () => (await import("./say")).sayCommand,
|
|
17
|
+
stats: async () => (await import("./stats")).statsCommand,
|
|
18
|
+
"support-bundle": async () => (await import("./support-bundle")).supportBundleCommand,
|
|
19
|
+
completions: async () => (await import("./completions")).completionsCommand,
|
|
20
|
+
manpage: async () => (await import("./manpage")).manpageCommand,
|
|
21
|
+
mcp: async () => (await import("./mcp")).mcpCommand,
|
|
36
22
|
};
|
|
37
23
|
|
|
38
24
|
function isPathLike(arg: string): boolean {
|
|
@@ -46,9 +32,7 @@ function isFalsey(v: string): boolean {
|
|
|
46
32
|
return FALSEY_VALUES.has(v.trim().toLowerCase());
|
|
47
33
|
}
|
|
48
34
|
|
|
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.
|
|
35
|
+
// Captured at import so re-enabling colors never clobbers a user-exported NO_COLOR.
|
|
52
36
|
const USER_FORCED_NO_COLOR =
|
|
53
37
|
process.env.NO_COLOR !== undefined && !isFalsey(process.env.NO_COLOR);
|
|
54
38
|
|
|
@@ -105,47 +89,72 @@ export function resolveQuietMode(rawArgs: string[]): { quiet: boolean; rawArgs:
|
|
|
105
89
|
return { quiet: value, rawArgs: cleaned };
|
|
106
90
|
}
|
|
107
91
|
|
|
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) {
|
|
92
|
+
/**
|
|
93
|
+
* Sync NO_COLOR with the resolved color decision so engine subprocesses inherit
|
|
94
|
+
* the right value. Separated from setColorEnabled so it can be tested without
|
|
95
|
+
* picocolors side-effects.
|
|
96
|
+
*
|
|
97
|
+
* Never clears a NO_COLOR the user exported before this process started
|
|
98
|
+
* (USER_FORCED_NO_COLOR guard).
|
|
99
|
+
*/
|
|
100
|
+
export function applyColorEnv(disableColor: boolean): void {
|
|
101
|
+
if (disableColor) {
|
|
121
102
|
process.env.NO_COLOR = "1";
|
|
122
103
|
} else if (!USER_FORCED_NO_COLOR) {
|
|
123
104
|
delete process.env.NO_COLOR;
|
|
124
105
|
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Classify the first positional arg for routing.
|
|
110
|
+
*
|
|
111
|
+
* - `"subcommand"` — exact match in the known subcommand set
|
|
112
|
+
* - `"unknown"` — bare token that looks like a typo (not a flag, not path-like)
|
|
113
|
+
* - `"main"` — flags, path-like args, or no arg (→ transcribe / help)
|
|
114
|
+
*/
|
|
115
|
+
export function classifyFirstArg(
|
|
116
|
+
firstArg: string | undefined,
|
|
117
|
+
subcommandKeys: string[],
|
|
118
|
+
): "subcommand" | "unknown" | "main" {
|
|
119
|
+
if (!firstArg) return "main";
|
|
120
|
+
if (subcommandKeys.includes(firstArg)) return "subcommand";
|
|
121
|
+
// Flags and path-like tokens fall through to the main transcribe command.
|
|
122
|
+
if (firstArg.startsWith("-") || isPathLike(firstArg)) return "main";
|
|
123
|
+
return "unknown";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function runCli(rawArgs = process.argv.slice(2)): Promise<void> {
|
|
127
|
+
// Global flags resolved before citty so they apply to every command and never reach a subcommand's arg schema.
|
|
128
|
+
const color = resolveColorMode(rawArgs);
|
|
129
|
+
// 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`).
|
|
130
|
+
setColorEnabled(!color.disableColor);
|
|
131
|
+
applyColorEnv(color.disableColor);
|
|
125
132
|
|
|
126
133
|
const quiet = resolveQuietMode(color.rawArgs);
|
|
127
134
|
log.quietEnabled = quiet.quiet;
|
|
128
135
|
|
|
129
136
|
rawArgs = quiet.rawArgs;
|
|
130
137
|
const [firstArg, ...restArgs] = rawArgs;
|
|
138
|
+
const subcommandKeys = Object.keys(SUBCOMMANDS);
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
switch (classifyFirstArg(firstArg, subcommandKeys)) {
|
|
141
|
+
case "subcommand":
|
|
142
|
+
await runMain(await SUBCOMMANDS[firstArg!]!(), { rawArgs: restArgs });
|
|
143
|
+
return;
|
|
136
144
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
log.warn(`
|
|
145
|
+
case "unknown": {
|
|
146
|
+
// Extensionless existing files are valid transcription inputs; bare non-path tokens are likely command typos.
|
|
147
|
+
const suggestion = suggestCommand(firstArg!, subcommandKeys);
|
|
148
|
+
log.error(`unknown command '${firstArg}'`);
|
|
149
|
+
if (suggestion && suggestion !== firstArg) {
|
|
150
|
+
log.warn(`(Did you mean ${suggestion}?)`);
|
|
151
|
+
}
|
|
152
|
+
log.warn(`If this is an audio file, pass a path like './${firstArg}'.`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
break;
|
|
145
155
|
}
|
|
146
|
-
log.warn(`If this is an audio file, pass a path like './${firstArg}'.`);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
156
|
|
|
150
|
-
|
|
157
|
+
default:
|
|
158
|
+
await runMain((await import("./main")).mainCommand, { rawArgs });
|
|
159
|
+
}
|
|
151
160
|
}
|
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
|
|