Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/cli/src/commands/transcribe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe("transcribe command", () => {
new WhisperUnavailableError("whisper-cpp not found. Install: brew install whisper-cpp"),
);
vi.spyOn(console, "log").mockImplementation(() => {});
vi.spyOn(console, "error").mockImplementation(() => {});
});

afterEach(() => {
Expand All @@ -65,6 +66,15 @@ describe("transcribe command", () => {
expect(process.exitCode).toBe(0);
expect(trackTranscribeUnavailable).toHaveBeenCalledWith({ optional: true });
expect(trackCommandFailure).not.toHaveBeenCalled();

const diagnostic = vi.mocked(console.error).mock.calls.at(-1)?.[0];
expect(typeof diagnostic).toBe("string");
if (typeof diagnostic !== "string") throw new Error("Expected stderr diagnostic");
expect(JSON.parse(diagnostic)).toEqual({
level: "warning",
reason: "whisper_unavailable",
message: "whisper-cpp not found. Install: brew install whisper-cpp",
});
});

it("imports an SRT and exports an SRT sidecar from transcript.json", async () => {
Expand Down
12 changes: 12 additions & 0 deletions packages/cli/src/commands/transcribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,18 @@ async function transcribeAudio(
if (isWhisperUnavailable(err)) {
trackTranscribeUnavailable({ optional: opts.optional === true });
if (opts.json) {
// Keep the machine-readable result on stdout, but also surface the
// skipped prerequisite on stderr. Pipeline wrappers commonly discard
// successful stdout, so an optional exit 0 must not become silent.
if (opts.optional) {
console.error(
JSON.stringify({
level: "warning",
reason: "whisper_unavailable",
message,
}),
);
}
console.log(JSON.stringify({ ok: false, skipped: true, reason: "whisper_unavailable" }));
} else {
spin?.stop(c.warn(`Captions skipped — ${message}`));
Expand Down
15 changes: 14 additions & 1 deletion packages/cli/src/whisper/manager.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { describe, it, expect } from "vitest";
import { WhisperUnavailableError, isWhisperUnavailable } from "./manager.js";
import {
WhisperUnavailableError,
getInstallInstructions,
isWhisperUnavailable,
} from "./manager.js";

describe("isWhisperUnavailable", () => {
it("recognizes WhisperUnavailableError instances", () => {
Expand Down Expand Up @@ -28,3 +32,12 @@ describe("isWhisperUnavailable", () => {
expect(isWhisperUnavailable(undefined)).toBe(false);
});
});

describe("getInstallInstructions", () => {
it("points Windows users to the prebuilt x64 archive before the source-build fallback", () => {
const instructions = getInstallInstructions("win32");

expect(instructions).toContain("whisper-bin-x64.zip");
expect(instructions).toContain("cmake");
});
});
10 changes: 5 additions & 5 deletions packages/cli/src/whisper/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,15 @@ export function findWhisper(): WhisperResult | undefined {
return findFromEnv() ?? findFromSystem() ?? findBuiltBinary();
}

export function getInstallInstructions(): string {
if (platform() === "darwin") {
export function getInstallInstructions(targetPlatform: NodeJS.Platform = platform()): string {
if (targetPlatform === "darwin") {
return "brew install whisper-cpp";
}
if (platform() === "linux") {
if (targetPlatform === "linux") {
return "Build from source: https://github.com/ggml-org/whisper.cpp#building (requires cmake and a C compiler)";
}
if (platform() === "win32") {
return "Build with cmake: https://github.com/ggml-org/whisper.cpp#building";
if (targetPlatform === "win32") {
return "Download the prebuilt whisper-bin-x64.zip from https://github.com/ggml-org/whisper.cpp/releases/latest, or build with cmake: https://github.com/ggml-org/whisper.cpp#building";
}
return "See https://github.com/ggml-org/whisper.cpp#building";
}
Expand Down
Loading